WPF 数据触发器和 Storyboard

标签 wpf animation expression-blend

我试图在 ViewModel/Presentation Model 忙碌时触发进度动画。我有一个 IsBusy 属性,并将 ViewModel 设置为 UserControl 的 DataContext。当 IsBusy 属性为真时,触发“progressAnimation” Storyboard的最佳方式是什么? Blend 只允许我在 UserControl 级别添加事件触发器,并且我只能在我的数据模板中创建属性触发器。
“progressAnimation”被定义为用户控件中的资源。
我尝试将 DataTriggers 添加为 UserControl 上的样式,但是当我尝试启动 StoryBoard 时,出现以下错误:

'System.Windows.Style' value cannot be assigned to property 'Style' of object'Colorful.Control.SearchPanel'. A Storyboard tree in a Style cannot specify a TargetName. Remove TargetName 'progressWheel'.


ProgressWheel 是我要制作动画的对象的名称,因此删除目标名称显然不是我想要的。
我希望使用数据绑定(bind)技术在 XAML 中解决这个问题,而不必通过代码公开事件和启动/停止动画。

最佳答案

尽管建议将动画直接附加到要动画的元素的答案在简单的情况下解决了这个问题,但是当您有一个需要针对多个元素的复杂动画时,这实际上并不可行。 (当然,您可以将动画附加到每个元素,但管理起来非常糟糕。)

所以有另一种方法可以解决这个问题,让您使用 DataTrigger运行以命名元素为目标的动画。

在 WPF 中可以在三个位置附加触发器:元素、样式和模板。但是,前两个选项在这里不起作用。第一个被排除,因为 WPF 不支持使用 DataTrigger直接在一个元素上。 (据我所知,这并没有什么特别好的理由。据我记得,多年前当我向 WPF 团队的成员询问这个问题时,他们说他们很想支持它,但没有有时间让它工作。)样式已经过时了,因为正如您报告的错误消息所说,您不能在与样式关联的动画中定位命名元素。

这样就剩下模板了。您可以为此使用控制或数据模板。

<ContentControl>
    <ContentControl.Template>
        <ControlTemplate TargetType="ContentControl">
            <ControlTemplate.Resources>
                <Storyboard x:Key="myAnimation">

                    <!-- Your animation goes here... -->

                </Storyboard>
            </ControlTemplate.Resources>
            <ControlTemplate.Triggers>
                <DataTrigger
                    Binding="{Binding MyProperty}"
                    Value="DesiredValue">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard
                            x:Name="beginAnimation"
                            Storyboard="{StaticResource myAnimation}" />
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <StopStoryboard
                            BeginStoryboardName="beginAnimation" />
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </ControlTemplate.Triggers>

            <!-- Content to be animated goes here -->

        </ControlTemplate>
    </ContentControl.Template>
<ContentControl>

通过这种结构,WPF 很乐意让动画引用模板内的命名元素。 (我在这里把动画和模板内容都留空了——显然你会用你的实际动画和内容来填充它。)

这适用于模板而不是样式的原因是,当您应用模板时,它定义的命名元素将始终存在,因此在该模板范围内定义的动画引用这些元素是安全的。样式通常不是这种情况,因为样式可以应用于多个不同的元素,每个元素可能具有完全不同的视觉树。 (即使在可以确定所需元素会存在的情况下,它也会阻止您执行此操作,这有点令人沮丧,但也许有些东西使得动画很难绑定(bind)到右侧的命名元素时间。我知道 WPF 中有很多优化可以使样式的元素能够被有效地重用,所以也许其中之一就是难以支持的原因。)

关于WPF 数据触发器和 Storyboard,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/80388/

相关文章:

c# - WPF- 将列表绑定(bind)到 ListView

c# - 启动/退出 Android.Provider.Settings Activity 时如何处理动画?

animation - 编写3D动画?

c# - Silverlight:在代码隐藏中切换 CustomVisualStateManager 的 VisualStates

wpf - ViewModel 处理事件

c# - WPF 应用程序的入口点是什么?

c# - 关注 gridview 中的文本框

android - 如何在android中使用不同图像在启动画面上显示动画

silverlight - 什么是 d :IsOptimized in Expressions Blend?

silverlight - 如何在 Blend 中编辑路径