Раскадровка не найдена в названии области стиля - PullRequest
4 голосов
/ 29 марта 2012

Проблема в том, что если я основываю стиль на втором стиле, который содержит раскадровку, в Trigger.ExitAction есть исключение.

  • Если я наведу курсор мыши на один из прямоугольников в демонстрационном примере ниже, раскадровка запустится, и прямоугольники изменят цвет.
  • Когда мышь покидает красный прямоугольник с style = 'rectStyle', раскадровка удаляется.
  • Когда мышь покидает синий прямоугольник (который использует производный стиль), я получаю это исключение:

    InvalidOperationException: Имя MouseOverStoryboard не найдено в области имен System.Windows.Style.

Итак:

  • Допустимо ли иметь раскадровку в базовом стиле?
  • Есть ли более явный способ обращения к BeginStoryboardName, чтобы эта ошибка не возникала?
  • Есть еще предложения?

В конце концов я пытаюсь добиться повторного использования стиля, содержащего триггеры и раскадровки в нескольких других стилях.

Вот простой код, демонстрирующий проблему:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.Resources>
        <Style x:Key="rectStyle" TargetType="{x:Type Rectangle}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard x:Name="MouseOverStoryboard">
                            <Storyboard>
                                <ColorAnimation To="PaleGoldenrod" 
                                   Storyboard.TargetProperty="(Fill).(Color)" 
                                   Duration="0:0:1"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <StopStoryboard BeginStoryboardName="MouseOverStoryboard"/>
                    </Trigger.ExitActions>
                </Trigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}" 
               BasedOn="{StaticResource rectStyle}"/>
    </Grid.Resources>

    <Rectangle Grid.Row="0" Width="100" Height="100" Fill="Red" 
               Style="{StaticResource rectStyle}" />
    <Rectangle Grid.Row="1" Width="100" Height="100" Fill="Blue" 
               Style="{StaticResource rectStyle2}" />
</Grid>

Ответы [ 2 ]

6 голосов
/ 09 апреля 2012

Лучше всего избегать производных стилей, если вы хотите включить StopStoryboard. На самом деле есть 2 экземпляра стиля, и область действия неправильна для производного стиля. Я считаю, что это по замыслу. Вы можете абстрагировать эту раскадровку во внешнюю область ресурсов и дублировать триггеры в обоих стилях, ссылаясь на раскадровку по StaticResource. Это может не решить вашу проблему, поскольку у вас могут быть определенные требования к производным стилям, но я не думаю, что у вас, к сожалению, есть выбор.

Поскольку вы вообще не можете наследовать от базового стиля, если хотите использовать StopStoryboard, вам придется сделать что-то вроде этого:

<Grid>
<Grid.RowDefinitions>
  <RowDefinition/>
  <RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
  <Storyboard x:Key="mouseOver">
    <ColorAnimation
      AutoReverse="True"
      Duration="0:0:1"
      RepeatBehavior="Forever"
      Storyboard.TargetProperty="(Fill).(Color)"
      To="PaleGoldenrod"/>
  </Storyboard>
  <Style x:Key="rectStyle" TargetType="{x:Type Rectangle}">
    <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="True">
        <Trigger.EnterActions>
          <BeginStoryboard x:Name="MouseOverStoryboard" Storyboard="{StaticResource mouseOver}"/>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
          <StopStoryboard BeginStoryboardName="MouseOverStoryboard"/>
        </Trigger.ExitActions>
      </Trigger>
    </Style.Triggers>
  </Style>
  <Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}">
    <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="True">
        <Trigger.EnterActions>
          <BeginStoryboard x:Name="MouseOverStoryboard1" Storyboard="{StaticResource mouseOver}"/>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
          <StopStoryboard BeginStoryboardName="MouseOverStoryboard1"/>
        </Trigger.ExitActions>
      </Trigger>
    </Style.Triggers>
  </Style>
</Grid.Resources>
<Rectangle
  Width="100"
  Height="100"
  Grid.Row="0"
  Fill="Red"
  Style="{StaticResource rectStyle}"/>
<Rectangle
  Width="100"
  Height="100"
  Grid.Row="1"
  Fill="Blue"
  Style="{StaticResource rectStyle2}"/>

2 голосов
/ 21 марта 2016

Просто наткнулся на это из-за той же проблемы.Существует другое решение, хотя и несколько неуклюжее.

Анимации в свойствах перезаписываются при применении другой анимации, поэтому вы можете использовать другую BeginStoryboard в ExitActions триггера для перезаписи предыдущей и использовать FillBehaviorСтоп для автоматического удаления этого.

К сожалению, комбинация Duration = 0, FillBehavior = Stop и никакого целевого значения не работает, поэтому вам нужно установить очень короткую продолжительность для этой анимации.

В вашем примере:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.Resources>
        <Style x:Key="rectStyle" TargetType="{x:Type Rectangle}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation To="PaleGoldenrod" 
                                   Storyboard.TargetProperty="(Fill).(Color)" 
                                   Duration="0:0:1"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <BeginStoryboard>
                            <Storyboard FillBehavior="Stop">
                                <ColorAnimation 
                                   Storyboard.TargetProperty="(Fill).(Color)" 
                                   Duration="0:0:0.0000001"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.ExitActions>
                </Trigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}" 
               BasedOn="{StaticResource rectStyle}"/>
    </Grid.Resources>

    <Rectangle Grid.Row="0" Width="100" Height="100" Fill="Red" 
               Style="{StaticResource rectStyle}" />
    <Rectangle Grid.Row="1" Width="100" Height="100" Fill="Blue" 
               Style="{StaticResource rectStyle2}" />
</Grid>
...