一个简单的需求:当程序发生异常时候,在界面上动画显示异常信息。

这个需求看似简单,只需要try……catch到异常,然后把异常的信息写入界面就OK了。

但在MVVM时,就不是这么简单了。MVVM模式下,追求前后端的分离。然后catch到的异常,也只能在后台代码中。如果传递到前台呢?

这自然就想到了Binding。在ViewModel中定义一个属性接收异常信息。然后在xaml中去绑定这个属性,就可以显示它了。

如下代码所示:

  C#:

  Xaml:

<TextBlock Text="{Binding Exception}"/>

C#代码:
/// <summary>
/// 数据类
/// </summary>
public class BTN:NotifyObject
{ public string Exception
{
get => exception;
set
{
exception = value;
OnPropertyChanged();
}
}
string exception = string.Empty;
}
  

如此一来,只需要给Exception属性赋值,TextBlock就能显示了。

OK,基本需求搞定。当如何使用动画呢?

首先,实现这种动画有三种方式:

  1. 改变TextBlock的Visibility属性,从Hidden 到 Visible。这中方式会用到KeyFrameAnimation。

  2. 改变TextBlock的Height属性,从0 到40(或者30),它就会有个“长高”的过程。

  3. 改变TextBlock的Opacity属性,从0到1,它就会有个慢慢显现的过程。

这里推荐使用第2或者第3中。因为它们使用的都是DoubleAnimation对象,比第一种使用KeyFrameAnimation对象要简单许多。

其次,如何触发动画呢?

在传统的编程模式下,只要在给Exception属性赋值时,控制TextBlock去显示动画就搞定了。但现在实在MVVM模式下!后台拿不到前台元素!

此时,触发器就发挥作用了。即,当某一个属性的值为特定值时,执行某些动作。

如果使用TextBlock的Text属性作为触发器,在Xaml中Value值不好写(因为在Xaml中,唯一能确定的string类型的值是Null或者String.Empty)。

因此这里可以为TextBlock添加一个附件属性,让它去绑定一个值。当这个属性的值满足条件的时候,就触发动画。

看代码吧:

   /// <summary>
/// 数据类
/// </summary>
public class BTN:NotifyObject
{ public string Exception
{
get => exception;
set
{
exception = value;
OnPropertyChanged(); HasException = !string.IsNullOrWhiteSpace(value);
}
}
string exception = string.Empty; // 添加HasException属性,用于前台附加属性的绑定
public bool HasException
{
get=>hasException;
set
{
hasException = value;
OnPropertyChanged();
}
}
bool hasException = false;
}
  
  public class NotifyUI
{
     // 定义附加属性,用于控件去绑定后台属性
private static readonly DependencyProperty HasMessageProperty = DependencyProperty.RegisterAttached(
"HasMessage", typeof(bool),typeof(NotifyUI),new PropertyMetadata(false)); public static void SetHasMessage(DependencyObject element, bool value) => element.SetValue(HasMessageProperty, value); public static bool GetHasMessage(DependencyObject element) => (bool)element.GetValue(HasMessageProperty);
}
        <TextBlock VerticalAlignment="Bottom"
Background="Yellow"
Height="0"
Text="{Binding Exception}"
local:NotifyUI.HasMessage="{Binding HasException}">  <!-- 使用附加属性去绑定后台的HasException属性 -->
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
              <!-- 设置触发器。当附加属性的值为True时,开始动画 -->
<Trigger Property="local:NotifyUI.HasMessage" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
                        <!-- 希望动画播放完毕后的,暂定一段时间,然后自动消退。这里不使用AutoReverse = True,因为在消退前不会暂定。-->
<DoubleAnimation To="40" Duration="0:0:0.2" Storyboard.TargetProperty="Height">
<DoubleAnimation.EasingFunction>
<BounceEase EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>

                        <!-- 设置BeignTime,是在第一个动画播放完之后,与第二个动画开始播放之间有时间间隔 -->
<DoubleAnimation To="0" Duration="0:0:0.2" Storyboard.TargetProperty="Height" BeginTime="0:0:1.2">
<DoubleAnimation.EasingFunction>
<BounceEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>

如此,就通过两个属性,在MVVM模式下,完成了动画的触发。

WPF 在MVVM模式下应用动画的更多相关文章

  1. 笔记03 wpf 在MVVM模式下怎样在Viewmodel里面获得view的控件对象

     转自http://blog.csdn.net/qing2005/article/details/6601199http://blog.csdn.net/qing2005/article/detail ...

  2. WPF中MVVM模式下控件自有的事件绑定

    1.原因 在WPF中单纯的命令绑定往往不能满足覆盖所有的事件,例如ComboBox的SelectionChanged事件,DataGrid的SelectionChanged事件等等,这时就可以用事件绑 ...

  3. WPF:MVVM模式下ViewModel关闭View

    不外乎两种基本方法. 消息通知和参数传递. 一.消息通知 利用View里的IsEnable属性 原理是这样的: 1.UI中的IsEnabled绑定VM中的属性 2.UI的后台代码中,注册IsEnabl ...

  4. WPF 在MVVM模式下弹出子窗体的方式

    主要是通过一个WindowManager管理类,在window后台代码中通过WindowManager注册需要弹出的窗体类型,在ViewModel通过WindowManager的Show方法,显示出来 ...

  5. WPF:MVVM模式下ViewModel调用View

    两种基本方法: 消息通知和参数传递 一.消息通知 利用View里的IsEnable属性 原理是这样的: 1.UI中的IsEnabled绑定VM中的属性 2.UI的后台代码中,注册IsEnableCha ...

  6. WPF中在MVVM模式下,后台绑定ListCollectionView事件触发问题

    问题:WPF中MVVM模式下 ListView绑定ListCollectionView时,CurrentChanged无法触发 解决方案: 初期方案:利用ListView的SelectionChang ...

  7. WPF实战案例-MVVM模式下在Xaml中弹出窗体

    相信很多学习和开发wpf项目的同学都了解过mvvm模式,同样,在mvvm模式下会有一个不可忽视的问题,就是怎么在xaml中弹出窗体,而不破坏MVVM本身的结构. 关于弹出窗体的方式还是很多的,本文先讲 ...

  8. MVVM模式下WPF动态绑定展示图片

    MVVM模式下WPF动态展示图片,界面选择图标,复制到项目中固定目录下面,保存到数据库的是相对路径,再次读取的时候是根据数据库的相对路径去获取项目中绝对路径的图片展示. 首先在ViewModel中 / ...

  9. wpf mvvm模式下CommandParameter传递多参

    原文:wpf mvvm模式下CommandParameter传递多参 CommandParameter一般只允许设置一次,所以如果要传递多参数,就要稍微处理一下.我暂时还没找到更好的方案,下面介绍的这 ...

  10. WPF MVVM模式下ComboBox级联效果 选择第一项

    MVVM模式下做的省市区的级联效果.通过改变ComboBox执行命令改变市,区. 解决主要问题就是默认选中第一项 1.首先要定义一个属性,继承自INotifyPropertyChanged接口.我这里 ...

随机推荐

  1. UCOS II 源码分析一

    再进行ucos操作系统源码分析前,先对ucos源码文件结构说个简单说明,只有掌握了源码文件结构才能在接下来的源码分析中逐渐感受到会当凌绝顶, 一览众山小,最后的感受就是RTOS也不是很神秘!下面以正点 ...

  2. Java的CompletableFuture,Java的多线程开发

    三.Java8的CompletableFuture,Java的多线程开发 1.CompletableFuture的常用方法 以后用到再加 runAsync() :开启异步(创建线程执行任务),无返回值 ...

  3. 安装vue后 vue -V查不到版本号 添加环境变量没反应

    萌新一枚,今天听老大说后续有项目要用vue,于是找教程自己先看看, 验证vue是否安装成功时,提示 'vue' 不是内部命令,也不是可运行的程序 有说把vue路径添加环境变量的,试了一下,不行(后来看 ...

  4. iOS网络数据指标收集

    在平时开发中有时候需要收集网络不同阶段性能数据来分析网络情况,下面总结了2种收集方式. 1.通过NSURLSession提供的代理方法收集 2.通过NSURLProtocol做统一网络请求拦截收集 通 ...

  5. Linux目录结构及常用命令

    目录 Linux目录结构... 1 Linux目录结构... 1 1. Linux常用命令... 4 1.1 Linux命令初体验... 4 1.2 文件目录操作命令... 8 1.3 拷贝移动命令. ...

  6. (内附示例源码)如何通过electron构建桌面跨平台音视频应用

    近年来,视频直播.直播带货.在线教育.在线医疗等音视频领域的相关行业都非常热门,成为大众瞩目的焦点. 在不久的将来,音视频技术渗透于各行各业,无处不在.从IoT网络到个人用户的移动设备,音视频技术以不 ...

  7. Redis的设计与实现(2)-链表

    链表在 Redis 中的应用非常广泛, 比如列表键的底层实现之一就是链表: 当一个列表键包含了数量比较多的元素, 又或者列表中包含的元素都是比较长的字符串时, Redis 就会使用链表作为列表键的底层 ...

  8. Django: Token分发

    Django后台token分发 在settings.py中引入 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'd ...

  9. 【Leaflet专题篇】L.tileLayer图层顺序问题

    1 问题复现 使用L.tileLayer加载底图(A.B.C)并使用layerControl管理.在用L.tileLayer.wms添加wms服务(D),当切换ABC时会压盖D视频中右下角的wms服务 ...

  10. 这些年写过的花式sql - 第3句 今日流失用户

    第3句 今日流失用户 需求: 当日流失用户的定义:昨天登录的,今天没登录的用户数 有一张用户登录日志表,有字段 date_stamp(日期时间戳),用户id(uid).如果用户在某天登录了,该表会有一 ...