翼度科技»论坛 编程开发 .net 查看内容

WPF入门教程系列二十七 ——DataGrid使用示例MVVM模式(4)

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
WPF入门教程系列目录WPF入门教程系列二——Application介绍WPF入门教程系列三——Application介绍(续)WPF入门教程系列四——Dispatcher介绍WPF入门教程系列五——Window 介绍
WPF入门教程系列十一——依赖属性(一)WPF入门教程系列十五——WPF中的数据绑定(一)  
    计算机界的顶极大牛们,站在金字塔尖的专家们,发明了模式,并大力推广模式,其目的就是想要达到高内聚低耦合。在WPF开发中,经典的编程模式是MVVM,是为WPF量身定做的模式,该模式充分利用了WPF的数据绑定机制,最大限度地降低了Xmal文件和CS文件的耦合度,也就是UI显示和逻辑代码的耦合度,如需要更换界面时,逻辑代码修改很少,甚至不用修改。与WinForm开发相比,我们一般在后台代码中会使用控件的名字来操作控件的各种属性,进行UI更新,而在WPF中通常是通过数据绑定来更新UI;在响应用户操作上,WinForm是通过控件的事件来处理,而WPF可以使用命令绑定的方式来处理,耦合度将降低。

     MVVM是Model、View、ViewModel的简写,MVVM的根本思想就是界面和业务功能进行分离,View的职责就是负责如何显示数据及发送命令,ViewModel的功能就是如何提供数据和执行命令。各司其职,互不影响。

       在实际的业务场景中我们经常会遇到客户对界面提出建议要求修改,使用MVVM模式开发,当设计的界面不满足客户时,我们仅仅只需要对View作修改,不会影响到ViewModel中的功能代码,减少了犯错的机会。随着功能地增加,系统会越来越复杂,程序会不停的增加View和ViewModel文件,这样一来会将复杂的界面分离成局部的View,局部的View对应局部的ViewModel,各个不同的功能点可能散落在不同的ViewModel中,每个ViewModel只专注自己职能之内的事情。

        理想情况下界面和逻辑是完全分离的,单方面更改界面时不需要对逻辑代码改动,同样的逻辑代码更改时也不需要更改界面。同一个ViewModel可以使用完全不用的View进行展示,同一个View也可以使用不同的ViewModel以提供不同的操作。

使用MVVM架构具有以下优势

1、易维护

2、灵活扩展

3、易测试

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

六、下拉框显示省份,实现保存功能

本篇文章我们来实现按钮的Click方法也采用绑定的形式,将业务逻辑代码写到业务逻辑类中,而不是写在View的后台cs文件中,这就需要使用Command指令。
在WPF中使用Command指令的步骤如下:
1)创建命令
2)绑定命令
3)设置命令源
4)设置命令目标
  WPF中Command指令的核心是继承System.Windows.Input.ICommand接口,所有Command指令对象都实现了此接口。当创建自己的Command指令时,不能直接实现ICommand接口,而是要使用System.Windows.Input.RouteCommand类,该类已经实现了ICommand接口,所有WPF中的Command指令都是RouteCommand类的实例。在程序中处理的大部分Command指令不是RoutedCommand对象,而是RoutedUICommand类的实例,它继承自RouteCommand类。
   WPF提供了一个很好的方式来解决事件绑定的问题--ICommand。很多控件都有Command属性,如果没有,我们可以将Command指令绑定到触发器上。接下来我们来先实现一个ICommand接口。ICommand需要用户定义两个方法bool CanExecute和void Execute。第一个方法可以让我们来判断是否可以执行这个命令,第二个方法就是我们具体的命令。
Command--ClickSaveAction

1. 在Visual Studio 2022的“解决方案资源管理器”中,使用鼠标右键单击“WpfGridDemo.NET7”项目,在弹出菜单中选择“添加-->新建文件夹”。 并将“新文件夹”改名为 “Command”。

2. 在Visual Studio 2022的解决方案资源管理器中,使用鼠标右键单击“Command”文件夹,在弹出菜单中选择“添加--> 类”,在弹出的“添加新项”对话框中,选择添加 “SaveCommand”类,这是一个我们要实现的保存操作指令,然后选择“添加”。

3.要实现在按钮的Command上绑定方法,代替Click事件,就需要SaveCommand实现ICommand接口,需要我们自己创建类型去实现接口的CanExecuteExecuteCanExecuteChanged,下面就是实现接口的代码:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows.Input;
  7. namespace WpfGridDemo.NET7.Command
  8. {
  9.     public class SaveCommand
  10.     {
  11.         /// <summary>
  12.         /// 命令能否执行
  13.         /// </summary>
  14.         readonly Func<bool> _canExecute;
  15.         /// <summary>
  16.         /// 命令执行的方法
  17.         /// </summary>
  18.         readonly Action _execute;
  19.         /// <summary>
  20.         /// 命令的构造函数
  21.         /// </summary>
  22.         /// <param name="action">命令需执行的方法</param>
  23.         /// <param name="canExecute">命令是否可以执行的方法</param>
  24.         public SaveCommand(Action action, Func<bool> canExecute)
  25.         {
  26.             _execute = action;
  27.             _canExecute = canExecute;
  28.         }
  29.         /// <summary>
  30.         /// 判断命令是否可以执行
  31.         /// </summary>
  32.         /// <param name="parameter"></param>
  33.         /// <returns></returns>
  34.         public bool CanExecute(Object parameter)
  35.         {
  36.             if (_canExecute == null)
  37.                 return true;
  38.             return _canExecute();
  39.         }
  40.         /// <summary>
  41.         /// 执行命令
  42.         /// </summary>
  43.         /// <param name="parameter"></param>
  44.         public void Execute(Object parameter)
  45.         {
  46.             _execute();
  47.         }
  48.         /// <summary>
  49.         /// 事件追加、移除
  50.         /// </summary>
  51.         public event EventHandler CanExecuteChanged
  52.         {
  53.             add
  54.             {
  55.                 if (_canExecute != null)
  56.                     CommandManager.RequerySuggested += value;
  57.             }
  58.             remove
  59.             {
  60.                 if (_canExecute != null)
  61.                     CommandManager.RequerySuggested -= value;
  62.             }
  63.         }
  64.     }
  65. }
复制代码
 
4.SaveCommand类就是为了在使用命令的时候, 创建一条命令出来用于绑定,这个类型接收两个参数,一个是命令执行的方法,另一个是有返回值的方法, 这个返回值bool用来确定,该条命令是否可以执行,如果命令不能被执行,则按钮的IsEnabled就被会设置成不可点击。
MainWindowVM中创建一个命令

1. 在Visual Studio 2022的“解决方案资源管理器”中,使用鼠标右键单击“WpfGridDemo.NET7”项目,在弹出菜单中选择“添加-->新建文件夹”。 并将“新文件夹”改名为 “ViewModel”。

2. 在Visual Studio 2022的解决方案资源管理器中,使用鼠标右键单击“ViewModel”文件夹,在弹出菜单中选择“添加--> 类”,在弹出的“添加新项”对话框中,选择添加 “MainWindowVM”类,这是一个ViewModel,然后选择“添加”。

3.之前我们已经创建了SaveCommand类,并实现了ICommand接口,下面在MainWindowVM中使用SaveCommand类,创建ClickSaveAction方法。
4.由于此次我们使用的是MVVM模块,无法直接使用界面中的控件DataGrid的属性,我们要将界面中所做的修改的数据保存到数据,则要在MainWindowVM添加一个绑定属性AreaVM,用于接收界面中传递过来的数据。具体如下代码:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows.Input;
  7. using WpfGridDemo.NET7.Entitys;
  8. namespace WpfGridDemo.NET7.ViewModel
  9. {
  10.     public class MainWindowVM
  11.     {
  12.         private Area m_Area;
  13.         /// <summary>
  14.         /// 员工数据
  15.         /// </summary>
  16.         public Area AreaVM
  17.         {
  18.             get { return m_Area; }
  19.             set { m_Area = value; }
  20.         }
  21.         /// <summary>
  22.         /// 命令要执行的方法
  23.         /// </summary>
  24.         void SaveExecute()
  25.         {
  26.             try
  27.            {
  28.                     GridDbContext db = new GridDbContext();
  29.                 var list=db.Area.AsTracking().ToList();
  30.                 Area modifyArea = list.Where(x=>x.Id==AreaVM.Id).FirstOrDefault();
  31.                 if (modifyArea != null)
  32.                 {
  33.                     modifyArea.Name = AreaVM.Name;
  34.                     modifyArea.Updated = DateTime.Now;
  35.                     db.SaveChanges();
  36.                 }
  37.             }
  38.             catch (Exception ex)
  39.             {
  40.                 throw ex;
  41.             }
  42.         }
  43.         /// <summary>
  44.         /// 命令是否可以执行
  45.         /// </summary>
  46.         /// <returns></returns>
  47.         bool CanSaveExecute()
  48.         {
  49.             return true;
  50.         }
  51.         /// <summary>
  52.         /// 创建新命令
  53.         /// </summary>
  54.         public ICommand ClickSaveAction
  55.         {
  56.             get
  57.             {
  58.                 return new Command.SaveCommand(SaveExecute, CanSaveExecute);
  59.             }
  60.         }
  61.     }
  62. }
复制代码
注意,创建这个新的命令的名字需要和我们界面按钮Command中绑定的名字一致,叫ClickSaveAction

来源:https://www.cnblogs.com/chillsrc/archive/2023/06/04/17455782.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具