【问题标题】:Trigger animation on ViewModel PropertyChanging / PropertyChanged在 ViewModel PropertyChanging / PropertyChanged 上触发动画
【发布时间】:2014-10-09 05:23:25
【问题描述】:

在 WPF 项目中,我有一个 ItemsControl 绑定到 ViewModel 的集合。它的 ItemTemplate 包含一个绑定到对象集合属性的 Image 控件。我有一个计时器,它每分钟从 JSON 服务获取新图像,并将它们分配给绑定到图像的属性。

我想做的是在该属性更改时触发一个简单的动画。特别是,我想在将新图像分配给我的属性之前触发一个简单的淡出动画,这将涉及 PropertyChanging 事件,以及 PropertyChanged 上的淡入动画,因此我可以从旧图像平滑过渡到新图像我的视图中的图像。

我尝试了以下来自another question 的内容,但这会在属性更改后触发动画,这不是我想要的:

<Image 
    x:Name="ChannelImage"
    Width="230" Height="230" 
    Source="{Binding ImageByteArray, Converter={StaticResource ByteArrayToBitmapImageConverter}, 
                                     NotifyOnTargetUpdated=True}">
    <Image.Triggers>
        <EventTrigger RoutedEvent="Binding.TargetUpdated">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation 
                        Storyboard.TargetName="ChannelImage"
                        Storyboard.TargetProperty="Opacity"
                        BeginTime="0:0:0"
                        Duration="0:0:1"
                        To="0"/>
                    <DoubleAnimation 
                        Storyboard.TargetName="ChannelImage"
                        Storyboard.TargetProperty="Opacity"
                        BeginTime="0:0:2"
                        Duration="0:0:1"
                        To="1"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Image.Triggers>
</Image>

任何帮助将不胜感激。

【问题讨论】:

    标签: wpf xaml mvvm storyboard inotifypropertychanged


    【解决方案1】:

    要淡出旧图像并淡入新图像并不容易。在您的情况下,我会执行以下操作来保持良好的关注点分离:

    1. 从 uri 中获取图像并在代码中创建一个新的Image。如果您需要这方面的更多信息,请查看this question on Stack Overflow
    2. 如果要应用 MVVM,应在视图模型中执行步骤 1 并设置引发PropertyChanged 的相应属性。否则,只需手动更新我在第 3 步中提到的相应控件即可。
    3. 实现一个自定义的ContentControl,它实际上完成了繁重的工作:当它的Content 属性发生变化时,它会淡出旧内容并淡入新内容。这是最难的部分,但如果您引入这个新控件,您可以像以前一样编写视图模型,并将所有淡入淡出的内容留给这个新控件。

    我为您实现了一个小项目,您可以通过此Dropbox link 下载它(需要 .NET 4.5)。我创建了 AnimatedContentControl 类,它是一个 WPF 自定义控件,在其默认控件模板内有两个 Content Presenter。在此控件上设置Content 属性时,旧内容将分配给淡出的OldContent 依赖属性。之后,新内容会淡入。所有这些都是使用故事板FadeInFromRight 完成的,它是控制模板资源的一部分。此情节提要在 AnimatedContentControl.cs 中的覆盖方法 OnContentChanged 中启动。

    其他类只是使用默认 MVVM 模式的 MainWindowMainWindowViewModel

    如果您有任何问题,请随时提出。我希望我能帮助你解决这个问题。

    【讨论】:

    • 非常感谢您花时间创建示例项目。我可能不会想出这样的解决方案,因为我的自定义控制技能不是那么好。我会看看如何将它整合到我的项目中并进行报告。
    • 如果您愿意,可以将AnimatedContentControl.csIStoryboardFinder.csResourceDictionaryStoryboardFinder.csAnimatedContentControlDefaultStyle.xamlGeneric.xaml复制到您的项目中。这两个 xaml 文件都必须位于项目中名为 Themes 的文件夹中。之后,您可以像我在 MainWindow.xaml 中所做的那样绑定 content 属性。
    • +1 用于自定义控制,因为它只需插入简单的 View 和 ViewModel 即可使动画可重用。
    • 这只是史诗。您所做的非常复杂,但效果很好,您可以将其复制并粘贴到您的项目中,它会起作用。我用它来显示状态文本,它确实为我的应用程序增添了额外的润色。
    • 如果您使用它来呈现您自己的自定义控件(控件内的控件),您可能希望增加关键时间。我不得不增加关键时间以使更大的控件顺利进出。
    猜你喜欢
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 2014-03-25
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多