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

这个需求看似简单,只需要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. 深入 Hyperf:HTTP 服务启动时发生了什么?

    当我们创建 Hyperf 项目之后,只需要在终端执行 php bin/hyperf.php start 启动命令,等上几秒钟,就可以看到终端输出的 Worker 进程已启动,HTTP 服务监听在 95 ...

  2. Typo in static class property declarationeslint

    eslint 检测提示 Typo in static class property declarationeslint 找了半天原来是propTypes 写成了PropTypes (就是一个首字母大写 ...

  3. Multiserver游戏服务器Demo[C++&Lua]

    代码参考 代码文件参考下述详解的类图,工程参考第零章工程说明 关键特性 对Socket库进行封装,抹平Socket的Window&Linux的平台差异. C++嵌入lua脚本,增加开发者编码效 ...

  4. C# 版本特性一览

    前言 使用 C# 作为开发语言已经 15 个年头了,受惠于 C# 的不断更新,伴随着大量的新特性与大量语法糖,让我更加容易写出简洁.高效的代码.日常中大量特性早已信手拈来,当然从未尝试过的特性更是难以 ...

  5. DIY制作隔离信号注入变压器

    最近在学习模电知识,接触到了测量运放环路增益,需要使用合适的注入变压器,查找资料发现商用信号注入变压器价格昂贵,不适合个人学习使用.看到LOTO使用普通音频变压器做测试,也跟技术群友做了交流,尝试使用 ...

  6. STL-priority_queue(ACM)

    1.无法访问v.front().v.back() 2.是一个 堆,默认为大根堆,改造后为小根堆 大根堆 重构函数(默认)(大根堆) priority_queue<int> v; 基本操作 ...

  7. 前端学习C语言 - 第二篇(常量、运算符、控制和循环)

    常量.运算符.控制和循环 前文我们写了第一个 c 语言程序,了解了基本的数据类型.本篇将继续学习:常量.运算符.控制语句和循环语句. 常量 #define 常量 #define是用来定义常量和宏的预处 ...

  8. C# 图片转PDF,PDF增加水印文字

    好久没写博客了,今天给大家分享一个图片转PDF的相关操作,也算是一次总结吧. 首先需要准备动态库itextsharp.dll,这个dll去网上下载,都可以下载到,C#对PDF的操作都是基于这个类库来实 ...

  9. Reactor 模式与Tomcat中的Reactor

    系列文章目录和关于我 参考:[nio.pdf (oswego.edu)](https://gee.cs.oswego.edu/dl/cpjslides/nio.pdf) 一丶什么是Reactor Th ...

  10. EDP转LVDS屏转接板方案芯片CS5211替代CH7511B电路设计

    CS5211替代CH7511B电路设计: CS5211用于设计DP转LVDS转换器,DP转LVDS控制板,DP转LVDS转接板等产品设计,其性能和参数可以替代与兼容PS8622,PS8625,CH75 ...