WPF自学入门(十一)WPF MVVM模式Command命令

在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新。但是这并不是我们使用MVVM的正确方式。正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了Xaml文件和CS文件的耦合度,分离界面和业务逻辑,所以我们要尽可能的在View后台不写代码。但是这个例子中,我们将更新ViewModel的代码写在了View里,下一个例子中,我们要通过命令(Command)的来将Button的事件分离出来。

因为本文中需要使用Command命令,我们先来简单了解Command命令。在WPF中使用命令的步骤很简单

1.创建命令

2.绑定命令

3.设置命令源

4.设置命令目标

WPF中命令的核心是System.Windows.Input.ICommand接口,所有命令对象都实现了此接口。当创建自己的命令时,不能直接实现ICommand接口,而是要使用System.Windows.Input.RouteCommand类,该类已经实现了ICommand接口,所有WPF命令都是RouteCommand类的实例。在程序中处理的大部分命令不是RoutedCommand对象,而是RoutedUICommand类的实例,它继承自RouteCommand类。

WPF提供了一个很好的方式来解决事件绑定的问题--ICommand。很多控件都有Command属性,如果没有,我们可以将命令绑定到触发器上。接下来我们来先实现一个ICommand接口。ICommand需要用户定义两个方法bool CanExecute和void Execute。第一个方法可以让我们来判断是否可以执行这个命令,第二个方法就是我们具体的命令。

  1 using System;2 3 using System.Collections.Generic;4 5 using System.Linq;6 7 using System.Text;8 9 using System.Windows.Input;10 11  12 13 /***********************作者:黄昏前黎明后**********************************14 15 *   作者:黄昏前黎明后16 17 *   CLR版本:4.0.30319.4200018 19 *   创建时间:2018-04-05 22:57:5620 21 *   命名空间:Example322 23 *   唯一标识:b9043d4c-fdd7-4e0f-a324-00f0f09286d024 25 *   机器名称:HLPC26 27 *   联系人邮箱:hl@cn-bi.com28 29 *30 31 *   描述说明:32 33 *34 35 *   修改历史:36 37 *38 39 *40 41 *****************************************************************/42 43 namespace Example344 45 {46 47     public class RelayCommand : ICommand48 49     {50 51         #region 字段52 53         readonly Func<Boolean> _canExecute;54 55         readonly Action _execute;56 57         #endregion58 59  60 61         #region 构造函数62 63         public RelayCommand(Action execute)64 65             : this(execute, null)66 67         {68 69         }70 71         public RelayCommand(Action execute, Func<Boolean> canExecute)72 73         {74 75             if (execute == null)76 77                 throw new ArgumentNullException("execute");78 79             _execute = execute;80 81             _canExecute = canExecute;82 83         }84 85         #endregion86 87  88 89         #region ICommand的成员90 91         public event EventHandler CanExecuteChanged92 93         {94 95             add96 97             {98 99
100
101                 if (_canExecute != null)
102
103                     CommandManager.RequerySuggested += value;
104
105             }
106
107             remove
108
109             {
110
111
112
113                 if (_canExecute != null)
114
115                     CommandManager.RequerySuggested -= value;
116
117             }
118
119         }
120
121
122
123         [DebuggerStepThrough]
124
125         public Boolean CanExecute(Object parameter)
126
127         {
128
129             return _canExecute == null ? true : _canExecute();
130
131         }
132
133
134
135         public void Execute(Object parameter)
136
137         {
138
139             _execute();
140
141         }
142
143         #endregion
144
145     }
146
147 }
148
149  

我们再在我们的NameViewModel中声明一个ICommand字段:

 1 #region 命令2 3         void UpdateNameExecute()4 5         {6 7             this.UserName = "黄昏前黎明后";8 9             this.CompanyName = "中软易通科技";
10
11         }
12
13
14
15         bool CanUpdateNameExecute()
16
17         {
18
19             return true;
20
21         }
22
23
24
25         public ICommand UpdateName { get { return new RelayCommand(UpdateNameExecute, CanUpdateNameExecute); } }
26
27
28
29         #endregion

最后,我们再将事件绑定上这个Command:

<Button Content="更新" Command="{Binding UpdateName}" Margin="20"/>

运行一下,看结果。我们成功将事件分离了出来。

看到上面的结果,似乎目前为止我们已经很好的解决了所有的问题。我们看到运行的数据,事件都是绑定的,实现了界面的完美分离。实际在处理问题是好像需要考虑通用性,这时我们能否把MVVM提取出来作为一个框架,来去更好的解决问题。下一次我们一起来看看怎么进行提取成为通用框架。

本文的DEMO下载地址:WPFMVVMDemo2.zip

https://pan.baidu.com/s/1xZvsrMbDOXlpvDbCh2Af3Q 密码:6666

WPF自学入门(十)WPF MVVM简单介绍

   前面文章中,我们已经知道,WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI。

  我们不管是NET中还是WPF中使用模式目的就是想达到高内聚低耦合。在WPF开发中,经典的编程模式是MVVM,是为WPF量身定做的模式,该模式充分利用了WPF的数据绑定机制,最大限度地降低了Xmal文件和CS文件的耦合度,也就是UI显示和逻辑代码的耦合度,如需要更换界面时,逻辑代码修改很少,甚至不用修改。与WinForm开发相比,我们一般在后置代码中会使用控件的名字来操作控件的属性来更新UI,而在WPF中通常是通过数据绑定来更新UI;在响应用户操作上,WinForm是通过控件的事件来处理,而WPF可以使用命令绑定的方式来处理,耦合度将降低。

一、MVVM介绍

  MVVM是Model-View-ViewModel(模型-视图-视图模型)的缩写形式,它通常被用于WPF或Silverlight开发。我们可以通过下图来直观的理解MVVM模式:  

  1、View就是用xaml实现的界面,负责与用户交互,接收用户输入,把数据展现给用户。

  2、ViewModel是一个C#类,负责收集需要绑定的数据和命令,聚合Model对象,通过View类的DataContext属性绑定到View,同时也可以处理一些UI逻辑。

  3、Model,就是系统中的对象,可包含属性和行为。

  三者之间的关系:View对应一个ViewModel,ViewModel可以聚合N个Model,ViewModel可以对应多个View

二、MVVM的优势

MVVM的根本思想就是界面和业务功能进行分离,View的职责就是负责如何显示数据及发送命令,ViewModel的功能就是如何提供数据和执行命令。各司其职,互不影响。在实际的业务场景中我们经常会遇到客户对界面提出建议要求修改,使用MVVM模式开发,当设计的界面不满足客户时,我们仅仅只需要对View作修改,不会影响到ViewModel中的功能代码,减少了犯错的机会。随着功能地增加,系统越来越复杂,相应地程序中会增加View和ViewModel文件,将复杂的界面分离成局部的View,局部的View对应局部的ViewModel,功能点散落在各个ViewModel中,每个ViewModel只专注自己职能之内的事情。ViewModel包含了View要显示的数据,并且知道View的交互代码,所以ViewModel就像一个无形的View。使用MVVM架构具有以下优势

1、易维护

2、灵活扩展

3、易测试

4、用户界面设计师与程序开发者能更好的合作

三、MVVM简单示例

为了让大家直观地了解MVVM的编程模式,下面会用到前面讲到的数据绑定以及命令等知识。

新建WPF项目,名称WPFMVVMDemo。添加用户类,如下图

在WPF术语中,这个叫“模型”,GUI是“视图”。不可思议的是“视图模型”,通过数据绑定将它们绑在一起,它真的是一个很好的适配器能将模型变成某种WPF框架可以使用的东西。所以这个就是“模型”。

接下来我们会非常容易理解创建视图模型:

请注意这个视图模型不是十分正确的。因为我们在视图模型里暴露了属性,我们显然会想使在代码里改变的用户名和公司名自动的显示在视图上

后台代码:

运行结果:

这里我们点击更新按钮不会有任何反应,因为还没有实现数据绑定。此时视图不会收到任何的关于属性改变的通知。要解决这个问题我们必须实现名称为INotifyPropertyChanged的接口。任何实现了这个接口的类,当属性发生改变的时候会通知所有监听者,所以我们需要修改视图模型NameViewModel类:

这里会产生多个事件。首先,我们检查了我们是否真的改变了属性。第二,如果值已经改变,我们向所有监听者注册PropertyChanged事件。现在我们有了一个模型Name和一个视图模型NameViewModel。我们只需要在定义视图。只需要修改视图MainWindow:

运行结果:

本文的demo下载地址:WPFMVVMDemo1.zip

https://pan.baidu.com/s/18hKaRqZI1nwGgu_G0Qz84Q  密码:8888

WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍...相关推荐

  1. 《SpringCloud超级入门》Eureka自我保护模式和InstanceID的配置《十四》

    关闭自我保护 保护模式主要在一组客户端和 Eureka Server 之间存在网络分区场景时使用.一旦进入保护模式,Eureka Server 将会尝试保护其服务的注册表中的信息,不再删除服务注册表中 ...

  2. 泰凌微8258入门教程 环境篇⑤——不同SDK的区别和SDK文件内容的简单介绍

    文章目录 一.前文 二.不同SDK的区别 三.SDK文件内容 四.Android Apk 一.前文 最近挺多博友加我微信,问了我一些比较简单且基本的问题. 虽然比较简单且基本,但是架不住问的人多,我还 ...

  3. WPF中Mvvm模式的理解

    1. Mvvm是什么,Mvvm是怎么来的? Mvvm模式广泛应用在WPF项目开发中,使用此模式可以把UI和业务逻辑分离开,使UI设计人员和业务逻辑人员能够分工明确. Mvvm模式是根据MVP模式来的, ...

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

    wpf mvvm模式下CommandParameter传递多参 原文:wpf mvvm模式下CommandParameter传递多参 CommandParameter一般只允许设置一次,所以如果要传递 ...

  5. 设计模式学习笔记(十七)——Command命令模式

    设计模式学习笔记(十七)--Command命令模式 Command命令模式介绍: Command命令模式是一种对象行为型模式,它主要解决的问题是:在软件构建过程中,"行为请求者"与 ...

  6. Android开发之MVVM模式实践(六),2021字节跳动春招技术面试题

    以上是我们创建协程的实现方式,我们可以通过指定Dispatchers来决定协程到底在什么线程中工作,而其实Kotlin的协程核心库中也为我们提供封装好了的scope,例如MainScope,源码如下: ...

  7. java自学——java的基本讲解和变量、字符串、运算符的简单介绍

    java自学--java的基本讲解和变量.数组.字符串.运算符的简单介绍 hello world程序 java程序的结构 java语句的组成介绍 关键字 标识符 标识符的命名规则 分隔符 注释符 空白 ...

  8. WPF MVVM从入门到精通1:MVVM模式简介

    WPF MVVM从入门到精通1:MVVM模式简介 原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录 ...

  9. 【WPF】MVVM模式的3种command

    原文:[WPF]MVVM模式的3种command 1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL, ...

最新文章

  1. python判断一个数是整数、浮点数还是字符串
  2. 负数赋值给无符号数的陷阱【转】
  3. 辨异 —— 冠词(定冠词、不定冠词、零冠词)
  4. java应用高内存占用
  5. 网上整理的jQuery插件开发教程
  6. Python学习笔记:‘’AttributeError: NoneType object has no attribute‘’
  7. power系列服务器问题品管主任,了解 Power BI 管理员角色
  8. python sys.argv[]用法
  9. 深度 | 数据仓库分层存储技术揭秘
  10. 地铁 java_怎么用Java编写一个地铁售票机的程序?
  11. layerdate时间插件不允许选着部分置灰效果处理
  12. 学习笔记之——LaTeX的使用
  13. RF- BuiltIn_Run Keyword关键字系列
  14. 《Python基础教程(第3版)》笔记:第8章异常
  15. [模块加载失败:找不到指定的模块]——如何解决DLL加载问题?
  16. 数字电位器程控可调电阻IC
  17. ABBYY FineReader Pro for Mac有哪些特性(下)
  18. w10谷歌chrome关闭自动更新
  19. 进入BIOS+制作u盘启动盘+将u盘启动盘设置为开机首选方法
  20. win10键盘win键失效了

热门文章

  1. C语言 · 计算时间
  2. Python高级特性(切片,迭代,列表生成式,生成器,迭代器)
  3. sql server 2005 中的同义词
  4. 在windows7下安装CentOS
  5. 数据备份 另一服务器_为什么NAS网络存储服务器会受到如此多的关注?
  6. Xcode10 修改代码后,编译没有反应,或者导入头文件没有提示
  7. ping通网关不能上网_手机、电脑为什么连不上网(断网)?
  8. Xamarin.Forms的基本页面和基本视图
  9. ArduinoYun的电源插座
  10. php$上传_如何实现PHP上传视频的功能?(图文+视频)