虽然一次性背景更改很容易并且已经有很多答案,但我如何才能始终如一地对颜色更改进行动画处理(例如,不是一次,不是单一颜色(。
举一个玩具问题的例子,假设我有一个名为"红色"、"蓝色"和"绿色"的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上(