应用不只是包含textboxs和labels,还包含actions,如按钮和鼠标事件等。接下来我们加上一些像按钮这样的UI元素来看MVVM类怎么演变的。与之前的UI相比,这次我们加上一个"Cal Tax"按钮,当我们点击这个依赖于“sales amount”的按钮时,它会计算税费并显示在同窗口内。

  为了完成所述的功能,我们先在Model类中添加一个CalculateTax的方法。当这个方法被调用时,它根据工资范围来计算税费并把它储存在Tax这个属性中。

public class Customer
{ ... private double _Tax; public double Tax => _Tax; public void CalculateTax()
{
if (Amount > )
{
_Tax = ;
}
else if (Amount > )
{
_Tax = ;
}
else
{
_Tax = ;
}
}
}

  因为view model是model类的包装,我们需要在view model中创建一个方法来调用model的Calculate方法。

public void Calculate()
{
....
obj.CalculateTax();
}

  现在我们希望从界面上调用Calculate方法时使用XAML而不是后台代码。现在还不能在XAML中直接调用Calculate方法,这时我们需要用到WPF command类。

  如果你想用属性来传递数据到view model 我们需要用到bindings,如果你想要从view传递actions我们需要用到commands.  

  所有属于view的actions都被传递到command类,因此第一步就是创建command类。为了创建一个这样的command类我们需要像下面这样实现ICommand接口。

  有2个方法我们必须要实现,CanExecute和Execute。在Execute方法中,我们写当这个action发生时我们真的要执行的逻辑。在CanExecute方法中,我们写一些验证代码来确定我们的Execute方法是否应该被执行。

 public class ButtonCommand:ICommand
{
public bool CanExecute(object parameter)
{
//验证代码
} public void Execute(object parameter)
{
//执行逻辑
} public event EventHandler CanExecuteChanged;
}

  现在所有的actions调用时先来到command类然后再路由到view model 类。换句话说就是command类需要覆盖view model类。

  下面是一些简短的代码摘要。有4个重要的点需要记下来:

  1. 创建的view model对象是私有成员级别的对象。
  2. 这个对象将view model通过构造函数来传递。
  3. 暂时我们没有在CanExecute中添加验证代码,它永远返回true.
  4. 在Execute方法中我们调用了view model类的Calculate方法。
public class ButtonCommand:ICommand
{
private CustomerViewModel _obj; public ButtonCommand(CustomerViewModel obj)
{
_obj = obj;
}
public bool CanExecute(object parameter)
{
//验证代码
return true;
} public void Execute(object parameter)
{
//执行逻辑
_obj.Calculate();
} public event EventHandler CanExecuteChanged;
}

  在上面的command的代码中,view model对象通过构造函数来传递。因此view model类需要创建一个command对象并通过ICommand接口暴露这个command对象。这个ICommand接口会被利用然后在WPF XAML中调用。一些关于CustomerViewModel类去用command类的重点:

  1. command类是CustomerViewModel类的一个私有成员级别的对象。
  2. 在view model类中,当前实例通过构造函数传递给command类。当我们之前解释command类代码时,我们说command类的构造函数获取到view model类的实例。因此在这一节中,我们把当前实例传递给command类。
  3. command对象以ICommand接口的形式暴露出来,这样它就可以在XAML里面来用了。
 public class CustomerViewModel
{
private readonly ButtonCommand _objButtonCommandCommand; public CustomerViewModel()
{
_objButtonCommandCommand=new ButtonCommand(this);
} public ICommand CalClick => _objButtonCommandCommand;
.....
}

  在UI上添加一个按钮来让它把按钮的行为和暴露为ICommand的方法关联起来。现在可以打开这个按钮的属性,找到命令属性,然后点击创建数据绑定。

  然后选择static resource然后给按钮加上ButtonCommand。

  当你去点击cal tax的按钮时,它回去执行CalculateTax方法并把tax的值存在_tax变量中。

  换句话中,UI不会自动的被通知关于Tax Cal.因此我们需要传递从对象到UI的某种通知告诉它们tax值已经改变了,然后UI来重新加载新的绑定的数据。

  在View model 勒种,我们需要发送一个通知时间到view上。  

  要在VIEW MODEL类中使用通知我们需要做3件事情。所有的3件事情在下面都标出来了。

  • 像如下代码一样实现INotifyPropertyChanged接口。一旦你实现了这个接口,它就创建了一个PropertyChangedEventHandler的事件对象。
  • 在Calculate方法中用PropertyChanged对象来引发事件,并且在这里面表示哪个属性会被通知。例子中使用的是Tax属性。为了安全起见我们在使用PropertyChanged对象之前先检查它是否为空。
public class CustomerViewModel:INotifyPropertyChanged
{
  ....
public void Calculate()
{
obj.CalculateTax();
OnPropertyChanged(nameof(Tax));
} public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

  当你运行这个应用时,你应该可以看到当你点击按钮时Tax的值也发生了变化。

[译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)的更多相关文章

  1. WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)

    到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击but ...

  2. WPF MVVM架构 EF、WCF、IOC 设计示例经典

    概要 该演示项目利用WPF应用程序构建的MVVM架构示例, 运用了Unity容器接口注入, MVVM的经典设计, 后台利用的EF+WCF. 后台实现: 从数据库生成的emdx 结合上下文进行数据交互, ...

  3. WPF MVVM 架构 Step By Step(2)(简单的三层架构示例及粘合代码GLUE code)

    我们第一步就是去了解三层架构和问题然后去看MVVM是怎么去解决这些问题的. 现在,感觉和事实是完全不同的两个东西.当你看到三层架构的框图的时候,你会觉得每层的职责被分配的很好.但是当你你真的去写代码的 ...

  4. WPF MVVM 架构 Step By Step(1)(介绍)

    生命就是我们从孩子开始,经过不断的学习成为成熟的成年人的进化过程.这和软件的架构有着异曲同工之妙,我们从基础的架构开始,随着需求和环境的变化不断的进化. 如果你去问任何一个.net开发者,什么是最基础 ...

  5. WPF MVVM 架构 Step By Step(4)(添加bindings - 完全去掉后台代码)

    之前的改进已经挺棒的,但是我们现在知道了后台代码的问题,那是否可能把后台代码全部去除呢?这时候就该WPF binding 和 commands 来做的事情了. WPF就是以超吊的binding,com ...

  6. WPF MVVM 架构 Step By Step(3)(把后台代码移到一个类中)

    我觉得大部分开发者应该已经知道怎么去解决这个问题.一般都是把后台代码(GLUE code)移动到一个类库.这个类库用来代表UI的属性和行为.任何代码当被移到一个类库中时都可以被编译成一个DLL,然后可 ...

  7. WPF学习笔记:(二)数据绑定模式与INotifyPropertyChanged接口

    数据绑定模式共有四种:OneTime.OneWay.OneWayToSource和TwoWay,默认是TwoWay.一般来说,完成数据绑定要有三个要点:目标属性是依赖属性.绑定设置和实现了INotif ...

  8. C# WPF - MVVM实现OPC Client管理系统

    前言 本文主要讲解采用WPF MVVM模式设计OPC Client的过程,算作对于WPF MVVM架构的学习记录吧!不足之处请不吝赐教,感谢! 涉及知识点 C#基础 Xaml基础 命令.通知和数据绑定 ...

  9. WPF Step By Step 系列-Prism框架在项目中使用

    WPF Step By Step 系列-Prism框架在项目中使用 回顾 上一篇,我们介绍了关于控件模板的用法,本节我们将继续说明WPF更加实用的内容,在大型的项目中如何使用Prism框架,并给予Pr ...

随机推荐

  1. Linux Bootup Time

    Linux Bootup Time 英文原文地址:http://elinux.org/Boot_Time 1.   简介 启动时间这一话题包括很多子话题,比如启动时间的衡量.启动时间的分析.人为因素分 ...

  2. cmd 命令行模式操作数据库 添加查询 修改 删除 ( 表 字段 数据)

    一 查看数据库.表.数据字段.数据 1 首先配置环境变量 进入mysql  或者通过一键集成工具 打开mysql命令行  或者mysql 可视化工具 打开命令行 进入这样的界面   不同的机器操作不同 ...

  3. Unity 总裁 John Riccitiello 发话:VR足以匹敌互联网

    在2017年Vision Summit大会的开幕演讲中,Unity首席执行官John Riccitiello向观众通报了开发人员如何利用Oculus,HTC等品牌创造的机遇来打造虚拟现实(VR)行业, ...

  4. bootstrap+masonry.js写瀑布流

    最近在用bootstrap写一个网站,其中有个图文展示的页面要用到瀑布流的效果.因为项目要求,项目要以bootstrap为基准,不准私自添加内联样式.内部样式,所以,自己写瀑布流就不行了,所以,根据要 ...

  5. Unity SLua 如何调用Unity中C#方法

    1.原理 就是通常在Lua框架中所说的,开放一个C#的web接口,或者叫做在Slua框架中注册函数. 2.作用 在Lua中调用C#中的方法,这个是在做热更新中很常用的一种方法,无论是slua,还是lu ...

  6. phpcms页面替换

    首页的替换流程首先要先把静态网页做出来,拿到这里来: 会发现这个网页里面少了图片,样式表也没有了 因为我们只把网页扔过来,所对应的图片和样式表没有扔过来 图片什么的应该扔到: 接着打开index.ht ...

  7. 关于for循环的几种经典案例

    由于for循环可以通过控制循环变量的初始值和循环结束条件来改变遍历的区间,所以在排序或者遍历的时候,利用for循环就比较简单,以下是本人学习后得到的一些总结案例. 1.排序的应用 1)交换排序:通过取 ...

  8. [转]JAVA自动装箱和拆箱

    http://www.cnblogs.com/dolphin0520/p/3780005.html 1.Java数据类型 装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类 ...

  9. HAProxy的三种不同类型配置方案

    haproxy是一款功能强大.灵活好用反向代理软件,提供了高可用.负载均衡.后端服务器代理的功能,它在7层负载均衡方面的功能很强大(支持 cookie track, header rewrite等等) ...

  10. centos6 安装 ansible_ui

    安装过程其实并不复杂,只不过出现的问题,遇到的问题比较多,也主要参考网上https://github.com/alaxli/ansible_ui/issues/15 中提到的方法,只不过我遇到自己的问 ...