在 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. 第一个方法可以让我们来判断是否可以执行这个命令, 第二个方法就是我们具体的命令.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows.Input;
- /*********************** 作者: 黄昏前黎明后 **********************************
- * 作者: 黄昏前黎明后
- * CLR 版本: 4.0.30319.42000
- * 创建时间: 2018-04-05 22:57:56
- * 命名空间: Example3
- * 唯一标识: b9043d4c-fdd7-4e0f-a324-00f0f09286d0
- * 机器名称: HLPC
- * 联系人邮箱: hl@cn-bi.com
- *
- * 描述说明:
- *
- * 修改历史:
- *
- *
- *****************************************************************/
- namespace Example3
- {
- public class RelayCommand : ICommand
- {
- #region 字段
- readonly Func<Boolean> _canExecute;
- readonly Action _execute;
- #endregion
- #region 构造函数
- public RelayCommand(Action execute)
- : this(execute, null)
- {
- }
- public RelayCommand(Action execute, Func<Boolean> canExecute)
- {
- if (execute == null)
- throw new ArgumentNullException("execute");
- _execute = execute;
- _canExecute = canExecute;
- }
- #endregion
- #region ICommand 的成员
- public event EventHandler CanExecuteChanged
- {
- add
- {
- if (_canExecute != null)
- CommandManager.RequerySuggested += value;
- }
- remove
- {
- if (_canExecute != null)
- CommandManager.RequerySuggested -= value;
- }
- }
- [DebuggerStepThrough]
- public Boolean CanExecute(Object parameter)
- {
- return _canExecute == null ? true : _canExecute();
- }
- public void Execute(Object parameter)
- {
- _execute();
- }
- #endregion
- }
- }
我们再在我们的 NameViewModel 中声明一个 ICommand 字段:
- #region 命令
- void UpdateNameExecute()
- {
- this.UserName = "黄昏前黎明后";
- this.CompanyName = "中软易通科技";
- }
- bool CanUpdateNameExecute()
- {
- return true;
- }
- public ICommand UpdateName { get { return new RelayCommand(UpdateNameExecute, CanUpdateNameExecute); } }
- #endregion
最后, 我们再将事件绑定上这个 Command:
<Button Content="更新" Command="{Binding UpdateName}" Margin="20"/>
运行一下, 看结果. 我们成功将事件分离了出来.
看到上面的结果, 似乎目前为止我们已经很好的解决了所有的问题. 我们看到运行的数据, 事件都是绑定的, 实现了界面的完美分离. 实际在处理问题是好像需要考虑通用性, 这时我们能否把 MVVM 提取出来作为一个框架, 来去更好的解决问题. 下一次我们一起来看看怎么进行提取成为通用框架.
本文的 DEMO 下载地址: WPFMVVMDemo2.zip
https://pan.baidu.com/s/1xZvsrMbDOXlpvDbCh2Af3Q 密码: 6666
来源: https://www.cnblogs.com/fly-bird/p/8724915.html