如何从实现它的控件启动在样式中定义的动画

本文关键字:样式 动画 定义 启动 控件 实现 | 更新日期: 2023-09-27 18:09:14

我在故事板中创建了一个名为"Error"的状态,并附带了一个动画。

我希望能够从使用该样式的控件中启动动画,每当满足特定条件时。

例如,当我的视图的DataContext中的一个属性被设置为某个值时。

如何启动在控件的样式中定义的故事板?

如何从实现它的控件启动在样式中定义的动画

在控件后面的代码中执行

Storyboard myStoryboard = this.FindResource("NameOfMyStoryBoard") as Storyboard;
if(myStoryboard != null)
{
    myStoryboard.Begin();
}

如果你的故事板没有被设置为资源,而是嵌入到你的样式中,那么声明它为资源,并在你的样式中引用它。

MSDN documentation: Storyboard

下面是如何在XAML中使用触发器:

<Style TargetType="Button" x:Key="MyStyle">
            <Style.Resources>
                <Storyboard x:Key="MyGetFocusAnimation">
                    <DoubleAnimation Storyboard.TargetProperty="Height"
                                     To="50"
                                     Duration="0:0:.3" />
                </Storyboard>
                <Storyboard x:Key="MyLoseFocusAnimation">
                    <DoubleAnimation Storyboard.TargetProperty="Height"
                                     To="30"
                                     Duration="0:0:.3" />
                </Storyboard>
            </Style.Resources>
            <Style.Triggers>
                <Trigger Property="IsMouseOver"
                         Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard Storyboard="{StaticResource MyGetFocusAnimation}" />
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <BeginStoryboard Storyboard="{StaticResource MyLoseFocusAnimation}" />
                    </Trigger.ExitActions>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin"
                         Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard Storyboard="{StaticResource MyGetFocusAnimation}" />
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <BeginStoryboard Storyboard="{StaticResource MyLoseFocusAnimation}" />
                    </Trigger.ExitActions>
                </Trigger>
            </Style.Triggers>
        </Style>

在你像上面那样定义了样式之后,你只需要告诉按钮要使用什么样式:

<Button Content="Content" Height="20" Width="100" Style="{StaticResource MyStyle}"/>

我最终创建了一个类来保存所有控件的验证依赖属性:

public class ValidationProperties
{
     #region IsValid Dependency Property
    /// <summary>
    /// An attached dependency property which provides an
    /// </summary>
    public static readonly DependencyProperty IsValidProperty;
    /// <summary>
    /// Gets the <see cref="IsValidProperty"/> for a given
    /// <see cref="DependencyObject"/>, which provides an
    /// </summary>
    public static bool GetIsValid(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsValidProperty);
    }
    /// <summary>
    /// Sets the attached <see cref="IsValidProperty"/> for a given
    /// <see cref="DependencyObject"/>, which provides an
    /// </summary>
    public static void SetIsValid(DependencyObject obj, bool value)
    {
        obj.SetValue(IsValidProperty, value);
    }
     #endregion IsValid Dependency Property
    static ValidationProperties()
    {
        // Register attached dependency property
        IsValidProperty = DependencyProperty.RegisterAttached("IsValid",
                                                            typeof(bool),
                                                            typeof(ValidationProperties), 
                                                            new FrameworkPropertyMetadata(true));
    }
}
在此之后,我修改了样式,使其根据使用样式的控件的属性值来启动动画:
(...)
<Trigger Property="AttachedProperties:ValidationProperties.IsValid" Value="false">
    <Trigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource ControlIsInvalid}"/>
    </Trigger.EnterActions>
</Trigger>
(...)

我最终将使用样式的控件的依赖属性绑定到模型中的值(通过视图模型):

<TextBox x:Name="UsernameTextbox"
       (...)
       AttachedProperties:ValidationProperties.IsValid="{Binding SessionHandler.SessionUser.UsernameIsValid}"/>