我遇到的问题是,如果我将样式基于包含故事板的第二种样式,那么Trigger.ExitAction就会出现异常。
当鼠标离开蓝色矩形(使用派生样式)时,我得到以下异常:
InvalidOperationException异常: 在'System.Windows.Style'的名称范围内找不到'MouseOverStoryboard'名称。
所以:
最后,我试图重新使用包含其他几种风格的触发器和故事板的样式。
以下是一些演示此问题的简单代码:
<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>
答案 0 :(得分:6)
如果要包含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}"/>
答案 1 :(得分:2)
由于遇到同样的问题,偶然发现了这一点。还有另一个解决方案,虽然有些笨重。
在应用另一个动画时,属性上的动画会被覆盖,因此您可以使用触发器的ExitActions中的另一个BeginStoryboard覆盖前一个,并使用Stop的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>