C# WPF动画-以编程方式切换的3种样式之间的转换

C# WPF动画-以编程方式切换的3种样式之间的转换,c#,wpf,C#,Wpf,我有表示“一项”的卡UserControl。我有多个“项目”显示在一个网格上,有许多行和列 Cardcontrol有3种可能的样式(比如states,但我没有使用UserControlstates,只使用样式)。这些样式表示“选定整行”、“选定一项”和“正常”状态 到目前为止,一切正常。现在,我想添加一些动画过渡到这个 我的行和卡“选择”是通过编程控制的(不是通过鼠标或键盘),我不知道如何在没有鼠标事件的情况下添加动画: 恐怕在应用样式时不会触发路由事件,但是每次更改样式属性时,您都可以处理加载

我有表示“一项”的
UserControl
。我有多个“项目”显示在一个
网格上,有许多行和列

Card
control有3种可能的样式(比如states,但我没有使用
UserControl
states,只使用样式)。这些样式表示“选定整行”、“选定一项”和“正常”状态

到目前为止,一切正常。现在,我想添加一些动画过渡到这个

我的行和卡“选择”是通过编程控制的(不是通过鼠标或键盘),我不知道如何在没有鼠标事件的情况下添加动画:


恐怕在应用
样式时不会触发路由事件,但是每次更改
样式
属性时,您都可以处理
加载的
事件并从可视树中卸载
用户控件
。例如:

<Style x:Key="SelectedRowBackground" TargetType="{x:Type UserControl}">
    <Style.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation
                                    Storyboard.TargetProperty="(UserControl.Background).(SolidColorBrush.Color)"
                                    To="Green" Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </Style.Triggers>
</Style>

这确实是一个解决办法。以编程方式应用动画而不使用
样式
可能会更好。无论如何,没有内置的方法来为
样式的实际应用设置动画。

您链接的示例演示了基于
事件触发器的动画,但这不是触发动作的唯一方法。您还可以基于
触发器
数据触发器
触发操作:

<Style.Triggers>
    <DataTrigger Binding="{Binding SomeStateProperty}" Value="SomeState">
        <DataTrigger.EnterActions>
            <BeginStoryboard>
                <!-- Animation to be applied when state changes from some other value to "SomeState" -->
            </BeginStoryboard>
        </DataTrigger.EnterActions>
        <DataTrigger.ExitActions>
            <BeginStoryboard>
                <!-- Animation to be applied when state changes from "SomeState" to some other value -->
            </BeginStoryboard>
        </DataTrigger.ExitActions>
    </DataTrigger>
</Style.Triggers>

<Style x:Key="SelectedRowBackground" TargetType="{x:Type UserControl}">
    <Style.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation
                                    Storyboard.TargetProperty="(UserControl.Background).(SolidColorBrush.Color)"
                                    To="Green" Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </Style.Triggers>
</Style>
private void UpdateSweepView()
{
    if (!sweepingColumns)
        foreach (CardControl item in currentCardControls)
        {
            if (item.Row == selectedRow)
                item.Style = (Style)FindResource("SelectedRowBackground");
            else
                item.Style = (Style)FindResource("NormalRowBackground");

            grid.Children.Remove(item);
            item.Unloaded += Uc_Unloaded;
        }
    ...

}

private void Uc_Unloaded(object sender, RoutedEventArgs e)
{
    grid.Children.Add(uc); //this will fire the Loading event and apply the animation
    uc.Unloaded -= Uc_Unloaded;
}
<Style.Triggers>
    <DataTrigger Binding="{Binding SomeStateProperty}" Value="SomeState">
        <DataTrigger.EnterActions>
            <BeginStoryboard>
                <!-- Animation to be applied when state changes from some other value to "SomeState" -->
            </BeginStoryboard>
        </DataTrigger.EnterActions>
        <DataTrigger.ExitActions>
            <BeginStoryboard>
                <!-- Animation to be applied when state changes from "SomeState" to some other value -->
            </BeginStoryboard>
        </DataTrigger.ExitActions>
    </DataTrigger>
</Style.Triggers>