DataTrigger 数据触发器触发动画的方式及问题解决
在WPF 中通过触发器实现动画的方式很常见,这里记录一下再使用DataTrigger 数据触发器触发动画的一些经验,以便备忘。
一、数据触发器 DataTrigger 与普通的触发器Trigger 区别:
- Trigger 普通触发器
<!--样式-->
<Style TargetType="TextBlock">
<Style.Triggers>
<!--这里是通过属性来决定触发条件的,修改样式-->
<Trigger Property="IsMouseOver" Value="true">
<Setter Foreground="Red"/>
</Trigger>
<Style.Triggers>
</Style>
<!--动画-->
<Style TargetType="TextBlock">
<Style.Triggers>
<!--这里是通过属性来决定触发条件的,修改样式-->
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryBoard>
<StoryBoard>
<DoubleAnimiation To="500" Duration="0:0:2" />
</StoryBoard>
</BeginStoryBoard>
<Trigger.EnterActions>
</Trigger>
<Style.Triggers>
</Style>
2.DataTrigger 数据触发器
<!--样式-->
<Style TargetType="TextBlock">
<Style.Triggers>
<!--这里使用的是Binding 而不再是Property,这样可以方便绑定其他对象,并通过其他对象的参考值变化决定是否触发样式修改或动画执行-->
<DataTrigger Binding={Binding ElementName="txt",Path=Text},Value="开" >
<Setter Property="Foreground" Value="Red" />
<DataTrigger>
</Style.Triggers>
</Style>
<!--动画-->
<Style TargetType="TextBlock">
<Style.Triggers>
<!--这里使用的是Binding 而不再是Property,这样可以方便绑定其他对象,并通过其他对象的参考值变化决定是否触发样式修改或动画执行-->
<DataTrigger Binding={Binding ElementName="txt",Path=Text},Value="开" >
<DataTrigger.EnterActions>
<BeginStoryBoard>
<StoryBoard>
<DoubleAnimation 此处省略动画 />
</StoryBoard>
</BeginStoryBoard>
<DataTrigger.EnterActions>
<DataTrigger>
</Style.Triggers>
</Style>
以上动画存在问题,即动画在第一个执行周期正常,以后就不在执行了。
解决方法:在定义故事板前增加删除故事板命令 <RemoveStoryBoard BeginStoryBoardName="bsb1" />
下面以具体示例演示:
Code
<Window x:Class="WpfApp11.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Window.Resources>
<Style x:Name="style1" TargetType="{x:Type StackPanel}">
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="{Binding ElementName=Window1,Path=ActualWidth}" />
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=txt,Path=Text}" Value="停放制动">
<DataTrigger.EnterActions>
<!--先删除可能已存在的故事板 -->
<RemoveStoryboard BeginStoryboardName="ATingFangZhiDong" />
<RemoveStoryboard BeginStoryboardName="ATingFangHuanJie" />
<BeginStoryboard x:Name="ATingFangZhiDong">
<Storyboard>
<DoubleAnimation To="500" Duration="0:0:2" AccelerationRatio="0.7" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=txt,Path=Text}" Value="停放缓解">
<DataTrigger.EnterActions>
<!--先删除可能已存在的故事板 -->
<RemoveStoryboard BeginStoryboardName="ATingFangZhiDong" />
<RemoveStoryboard BeginStoryboardName="ATingFangHuanJie" />
<BeginStoryboard x:Name="ATingFangHuanJie">
<Storyboard>
<DoubleAnimation To="0" Duration="0:0:2" AccelerationRatio="0.7" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel x:Name="Sp1" Background="LightBlue" Grid.Row="1">
</StackPanel>
<TextBox x:Name="txt" Height="25" Margin="10" Width="100" HorizontalAlignment="Left" />
</Grid>
</Window>