WPF 如何正确设置颜色变化的动画



虽然一次性背景更改很容易并且已经有很多答案,但我如何才能始终如一地对颜色更改进行动画处理(例如,不是一次,不是单一颜色(。
举一个玩具问题的例子,假设我有一个名为"红色"、"蓝色"和"绿色"的Rectangle和三个RadioButton,我如何对矩形的填充颜色进行动画处理,使其对应于选中的单选按钮(例如,每当您单击"蓝色"并且矩形变为蓝色时(?

<StackPanel HorizontalAlignment="Left">
<Rectangle Width="50" Height="50" Style="{StaticResource ColorChangingStyle}"/>
<RadioButton Name="Red" Content="Red" GroupName="Group1" IsChecked="True"/>
<RadioButton Name="Green" Content="Green" GroupName="Group1"/>
<RadioButton Name="Blue" Content="Blue" GroupName="Group1"/>
</StackPanel>

我现在面临的问题是,每当有多个动画附加到Rectangle的填充颜色时,由于动画优先级,它会以各种方式惨败,例如,如果有多个"红色"、"绿色"和"蓝色"触发器:

<DataTrigger Binding="{Binding IsChecked, ElementName=Blue}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="ToBlue">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" To="Blue" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
当您单击"绿色"时,">

填充"为蓝色,它将保持蓝色(因为"ToBlue"是在"ToGreen"下面定义的(。更糟糕的是,如果您事先尝试删除"ToBlue":

<RemoveStoryboard BeginStoryboardName="ToBlue"/>

它将从默认颜色动画化为绿色,而不是从蓝色变为绿色。

是的,问题是....这是一个"错误"。触发器是"样式"元素的旧方法。新方法使用视觉状态

一个例子是:

注意:此示例不适用于您。

<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ColorStates">
<VisualState Name="ToGreen">
<Storyboard>
<ColorAnimation To="Green" 
Storyboard.TargetProperty="Fill"/>
</Storyboard>
</VisualState>
<VisualState Name="ToBlue">
<Storyboard>
<ColorAnimation To="Blue" 
Storyboard.TargetProperty="Fill"/>
</Storyboard>
</VisualState>
<VisualState Name="ToRed">
<Storyboard>
<ColorAnimation To="Red" 
Storyboard.TargetProperty="Fill"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

然后为了改变状态,你可以使用一点C#

VisualStateManager.GoToState(YOUR_CONTROL, "YOUR_STATE", true);

或者如果它太丑,你可以做一个状态行为

public class StateBehavior 
{
public static readonly DependencyProperty StateProperty =
DependencyProperty.RegisterAttached("State", 
typeof(string), 
typeof(StateBehavior),
new UIPropertyMetadata(null, StateChanged));
internal static void StateChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) 
{
if (args.NewValue != null)
VisualStateManager.GoToState((FrameworkElement)target, args.NewValue, true);
}
}

并像这样使用它

<YOUR_CONTROL local:StateBehavior.State="{Binding Path=YOUR_STATE_DATA, Mode=TwoWay}" />

奖金

您可以将过渡用于某些效果(Ik 它的题外话(

PS:很抱歉没有展示如何解决您的问题。(我只是懒得切换到Windows,我目前在Linux上(

相关内容

  • 没有找到相关文章

最新更新