WPF动画仅在一个方向上工作
我正在制作一个由xaml中的单选按钮控制的“红绿灯”动画。我正在使用椭圆样式来更改颜色并设置运动动画。问题是,动画仅在椭圆向下移动(到较高的Canvas.Top值)时起作用,但在向上移动(到较低的Canvas.Top值)时不起作用 代码如下:WPF动画仅在一个方向上工作,wpf,xaml,Wpf,Xaml,我正在制作一个由xaml中的单选按钮控制的“红绿灯”动画。我正在使用椭圆样式来更改颜色并设置运动动画。问题是,动画仅在椭圆向下移动(到较高的Canvas.Top值)时起作用,但在向上移动(到较低的Canvas.Top值)时不起作用 代码如下: <Window x:Class="hw05.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quo
<Window x:Class="hw05.MainWindow"
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:hw05"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Red"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=RedRB}" Value="True">
<Setter Property="Fill" Value="Red"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.400" To="83">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=YellowRB}" Value="True">
<Setter Property="Fill" Value="Orange"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.400" To="133">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=GreenRB}" Value="True">
<Setter Property="Fill" Value="Green"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.400" To="183">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Canvas>
<RadioButton Name="RedRB" GroupName="One" IsChecked="True" Canvas.Left="50" Canvas.Top="100">first</RadioButton>
<RadioButton Name="YellowRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="150">second</RadioButton>
<RadioButton Name="GreenRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="200">third</RadioButton>
<Ellipse Name="Light" Width="50" Height="50" Canvas.Left="180" Canvas.Top="83"></Ellipse>
</Canvas>
</Window>
第一
第二
第三
您应该知道像Trigger
和DataTrigger
这样的触发器是基于状态的:您有一个enter操作来反映到状态的转换(例如,IsChecked
:false
=>true
),还有一个exit操作来反映从状态的转换(例如,IsChecked
:true
=>false
)。您当前仅为进入转换定义动画。因此,从动画的角度来看,进入状态永远不会保留。DataTrigger。EnterAction
将保留动画状态,直到DataTrigger。ExitAction
已执行=>基于状态
在您的场景中,触发基于事件的动画更有意义:动画在某个事件发生时执行(例如,RadioButton.Checked
),并一直保持到下一个事件发生。每个动画都会为上一个动画的值设置动画(如果FillBehavior=“hold”
,这是默认设置)
以下示例已将动画移动到画布
,因为这定义了所有参与元素的通用名称范围:
<Canvas>
<RadioButton Name="RedRB" GroupName="One" IsChecked="True" Canvas.Left="50" Canvas.Top="100">first</RadioButton>
<RadioButton Name="YellowRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="150">second</RadioButton>
<RadioButton Name="GreenRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="200">third</RadioButton>
<Ellipse Name="Light"
Fill="Red"
Width="50" Height="50"
Canvas.Left="180" Canvas.Top="83" />
<Canvas.Triggers>
<EventTrigger RoutedEvent="RadioButton.Checked" SourceName="RedRB">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"
Storyboard.TargetName="Light"
Duration="0:0:0.400" To="83" />
<ColorAnimation Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="Light"
To="Red" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="RadioButton.Checked" SourceName="YellowRB">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"
Storyboard.TargetName="Light"
Duration="0:0:0.400" To="133" />
<ColorAnimation Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="Light"
To="Yellow" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="RadioButton.Checked" SourceName="GreenRB">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"
Storyboard.TargetName="Light"
Duration="0:0:0.400" To="183" />
<ColorAnimation Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="Light"
To="Green" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
第一
第二
第三
您应该知道像Trigger
和DataTrigger
这样的触发器是基于状态的:您有一个enter操作来反映到状态的转换(例如,IsChecked
:false
=>true
),还有一个exit操作来反映从状态的转换(例如,IsChecked
:true
=>false
)。您当前仅为进入转换定义动画。因此,从动画的角度来看,进入状态永远不会保留。DataTrigger。EnterAction
将保留动画状态,直到DataTrigger。ExitAction
已执行=>基于状态
在您的场景中,触发基于事件的动画更有意义:动画在某个事件发生时执行(例如,RadioButton.Checked
),并一直保持到下一个事件发生。每个动画都会为上一个动画的值设置动画(如果FillBehavior=“hold”
,这是默认设置)
以下示例已将动画移动到画布
,因为这定义了所有参与元素的通用名称范围:
<Canvas>
<RadioButton Name="RedRB" GroupName="One" IsChecked="True" Canvas.Left="50" Canvas.Top="100">first</RadioButton>
<RadioButton Name="YellowRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="150">second</RadioButton>
<RadioButton Name="GreenRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="200">third</RadioButton>
<Ellipse Name="Light"
Fill="Red"
Width="50" Height="50"
Canvas.Left="180" Canvas.Top="83" />
<Canvas.Triggers>
<EventTrigger RoutedEvent="RadioButton.Checked" SourceName="RedRB">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"
Storyboard.TargetName="Light"
Duration="0:0:0.400" To="83" />
<ColorAnimation Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="Light"
To="Red" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="RadioButton.Checked" SourceName="YellowRB">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"
Storyboard.TargetName="Light"
Duration="0:0:0.400" To="133" />
<ColorAnimation Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="Light"
To="Yellow" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="RadioButton.Checked" SourceName="GreenRB">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"
Storyboard.TargetName="Light"
Duration="0:0:0.400" To="183" />
<ColorAnimation Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="Light"
To="Green" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
第一
第二
第三
为什么不直接设置From
?因为From值需要根据椭圆的位置进行更改,我不确定如何进行更改。为什么不直接设置From
?因为From值需要根据椭圆的位置进行更改,我不确定如何进行更改。