走进WPF之MVVM完整案例

您所在的位置:网站首页 架构教程 走进WPF之MVVM完整案例

走进WPF之MVVM完整案例

2024-07-13 13:59:44| 来源: 网络整理| 查看: 265

学习WPF如果不学MVVM,仿佛缺少了灵魂。那什么是MVVM呢?为什么要学MVVM呢,本以一个简单的增删改查的小例子,简述MVVM的基本知识及如何通过进行MVVM架构的程序开发,仅供学习分享使用,如有不足之处,还请指正。

什么是MVVM?

MVVM是Model-View-ViewModel的简写。它本质上就是MVC (Model-View- Controller)的改进版。即模型-视图-视图模型。分别定义如下:

【模型】指的是后端传递的数据。 【视图】指的是所看到的页面。 【视图模型】mvvm模式的核心,它是连接view和model的桥梁。它有两个方向: 一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。 二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。

MVVM示意图如下所示:

安装MvvmLight插件

项目名称右键-->管理NuGet程序包-->搜索MvvmLight-->安装。如下所示:

 

 弹出接受许可证窗口,点击【接受】如下所示:

 

 MvvmLight安装成功后,自动引用需要的第三方库,并默认生成示例内容,有些不需要的需要删除,如下所示:

MVVM示例截图

主要通过MVVM实现数据的CRUD【增删改查】基础操作,如下所示:

 MVVM开发步骤 1. 创建Model层

本例主要是对学生信息的增删改查,所以创建Student模型类,如下所示:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace WpfApp3.Models 8 { 9 /// 10 /// 学生类 11 /// 12 public class Student 13 { 14 /// 15 /// 唯一标识 16 /// 17 public int Id { get; set; } 18 19 /// 20 /// 学生姓名 21 /// 22 public string Name { get; set; } 23 24 /// 25 /// 年龄 26 /// 27 public int Age { get; set; } 28 29 /// 30 /// 班级 31 /// 32 public string Classes { get; set; } 33 } 34 } 2. 创建DAL层

为了简化示例,模拟数据库操作,构建基础数据,如下所示:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using WpfApp3.Models; 7 8 namespace WpfApp3.DAL 9 { 10 public class LocalDb 11 { 12 private List students; 13 14 public LocalDb() { 15 init(); 16 } 17 18 /// 19 /// 初始化数据 20 /// 21 private void init() { 22 students = new List(); 23 for (int i = 0; i < 30; i++) 24 { 25 students.Add(new Student() 26 { 27 Id=i, 28 Name=string.Format("学生{0}",i), 29 Age=new Random(i).Next(0,100), 30 Classes=i%2==0?"一班":"二班" 31 }); 32 } 33 } 34 35 /// 36 /// 查询数据 37 /// 38 /// 39 public List Query() 40 { 41 return students; 42 } 43 44 /// 45 /// 按名字查询 46 /// 47 /// 48 /// 49 public List QueryByName(string name) 50 { 51 return students.Where((t) => t.Name.Contains(name)).ToList();//FindAll((t) => t.Name.Contains(name)); 52 } 53 54 public Student QueryById(int Id) 55 { 56 var student = students.FirstOrDefault((t) => t.Id == Id); 57 if (student != null) 58 { 59 return new Student() { 60 Id=student.Id, 61 Name=student.Name, 62 Age=student.Age, 63 Classes=student.Classes 64 }; 65 } 66 return null; 67 } 68 69 70 /// 71 /// 新增学生 72 /// 73 /// 74 public void AddStudent(Student student) 75 { 76 if (student != null) 77 { 78 students.Add(student); 79 } 80 } 81 82 /// 83 /// 删除学生 84 /// 85 /// 86 public void DelStudent(int Id) 87 { 88 var student = students.FirstOrDefault((t) => t.Id == Id); //students.Find((t) => t.Id == Id); 89 if (student != null) 90 { 91 students.Remove(student); 92 } 93 94 } 95 } 96 97 98 } 3. 创建View层

View层与用户进行交互,用户数据的展示,及事件的响应。在本例中,View层主要有数据查询展示,新增及编辑页面。

在View层,主要是命令的绑定,及数据的绑定。

在DataGridTextColumn中通过Binding="{Binding Id}"的形式绑定要展示的列属性名。 在Button按钮上通过Command="{Binding AddCommand}"的形式绑定要响应的命令。 在TextBox文本框中通过Text="{Binding Search}"的形式绑定查询条件属性。

数据展示窗口,如下所示:

1 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

新增及编辑页面,如下所示:

1 9 10 11 12 13 14 15 修改学生信息 16 17 姓名 18 19 年龄 20 21 班级 22 23 24 25 26 27 28 29 3. 创建ViewModel层

ViewModel层是MVVM的核心所在,起到承上启下的作用。ViewModel需要继承GalaSoft.MvvmLight.ViewModelBase基类。

ViewModel中属性实现数据的绑定,命令实现用户交互的响应。如下所示:

1 using GalaSoft.MvvmLight; 2 using GalaSoft.MvvmLight.Command; 3 using System.Collections.Generic; 4 using System.Collections.ObjectModel; 5 using System.Linq; 6 using System.Windows; 7 using WpfApp3.DAL; 8 using WpfApp3.Models; 9 using WpfApp3.Views; 10 11 namespace WpfApp3.ViewModel 12 { 13 /// 14 /// 15 /// 16 public class MainViewModel : ViewModelBase 17 { 18 #region 属性及构造函数 19 20 private LocalDb localDb; 21 22 private ObservableCollection gridModelList; 23 24 public ObservableCollection GridModelList 25 { 26 get { return gridModelList; } 27 set 28 { 29 gridModelList = value; 30 RaisePropertyChanged(); 31 } 32 } 33 34 /// 35 /// 查询条件 36 /// 37 private string search; 38 39 public string Search 40 { 41 get { return search; } 42 set 43 { 44 search = value; 45 RaisePropertyChanged(); 46 } 47 } 48 49 50 /// 51 /// 52 /// 53 public MainViewModel() 54 { 55 localDb = new LocalDb(); 56 QueryCommand = new RelayCommand(this.Query); 57 ResetCommand = new RelayCommand(this.Reset); 58 EditCommand = new RelayCommand(this.Edit); 59 DeleteCommand = new RelayCommand(this.Delete); 60 AddCommand = new RelayCommand(this.Add); 61 } 62 63 #endregion 64 65 #region command 66 67 /// 68 /// 查询命令 69 /// 70 public RelayCommand QueryCommand { get; set; } 71 72 /// 73 /// 重置命令 74 /// 75 public RelayCommand ResetCommand { get; set; } 76 77 /// 78 /// 编辑 79 /// 80 public RelayCommand EditCommand { get; set; } 81 82 /// 83 /// 删除 84 /// 85 public RelayCommand DeleteCommand { get; set; } 86 87 /// 88 /// 新增 89 /// 90 public RelayCommand AddCommand { get; set; } 91 92 #endregion 93 94 public void Query() 95 { 96 List students; 97 if (string.IsNullOrEmpty(search)) 98 { 99 students = localDb.Query(); 100 } 101 else 102 { 103 students = localDb.QueryByName(search); 104 } 105 106 GridModelList = new ObservableCollection(); 107 if (students != null) 108 { 109 students.ForEach((t) => 110 { 111 GridModelList.Add(t); 112 }); 113 } 114 } 115 116 /// 117 /// 重置 118 /// 119 public void Reset() 120 { 121 this.Search = string.Empty; 122 this.Query(); 123 } 124 125 /// 126 /// 编辑 127 /// 128 /// 129 public void Edit(int Id) 130 { 131 var model = localDb.QueryById(Id); 132 if (model != null) 133 { 134 StudentWindow view = new StudentWindow(model); 135 var r = view.ShowDialog(); 136 if (r.Value) 137 { 138 var newModel = GridModelList.FirstOrDefault(t => t.Id == model.Id); 139 if (newModel != null) 140 { 141 newModel.Name = model.Name; 142 newModel.Age = model.Age; 143 newModel.Classes = model.Classes; 144 } 145 this.Query(); 146 } 147 } 148 } 149 150 /// 151 /// 删除 152 /// 153 /// 154 public void Delete(int Id) 155 { 156 var model = localDb.QueryById(Id); 157 if (model != null) 158 { 159 var r = MessageBox.Show($"确定要删除吗【{model.Name}】?","提示",MessageBoxButton.YesNo); 160 if (r == MessageBoxResult.Yes) 161 { 162 localDb.DelStudent(Id); 163 this.Query(); 164 } 165 } 166 } 167 168 /// 169 /// 新增 170 /// 171 public void Add() 172 { 173 Student model = new Student(); 174 StudentWindow view = new StudentWindow(model); 175 var r = view.ShowDialog(); 176 if (r.Value) 177 { 178 model.Id = GridModelList.Max(t => t.Id) + 1; 179 localDb.AddStudent(model); 180 this.Query(); 181 } 182 } 183 } 184 } 4. 数据上下文

当各个层分别创建好后,那如何关联起来呢?答案就是DataContext【数据上下文】。

查询页面上下文,如下所示:

1 namespace WpfApp3 2 { 3 /// 4 /// MainWindow.xaml 的交互逻辑 5 /// 6 public partial class MainWindow : Window 7 { 8 public MainWindow() 9 { 10 InitializeComponent(); 11 MainViewModel viewModel = new MainViewModel(); 12 viewModel.Query(); 13 this.DataContext = viewModel; 14 } 15 } 16 }

新增页面上下文,如下所示:

1 namespace WpfApp3.Views 2 { 3 /// 4 /// StudentWindow.xaml 的交互逻辑 5 /// 6 public partial class StudentWindow : Window 7 { 8 public StudentWindow(Student student) 9 { 10 InitializeComponent(); 11 this.DataContext = new 12 { 13 Model = student 14 }; 15 } 16 17 private void btnSave_Click(object sender, RoutedEventArgs e) 18 { 19 this.DialogResult = true; 20 } 21 22 private void btnCancel_Click(object sender, RoutedEventArgs e) 23 { 24 this.DialogResult = false; 25 } 26 } 27 } 总结

MVVM具有低耦合,可重用,可测试,独立开发的优点,核心要素就两个:

属性发生变化时的通知,即可达到数据的实时更新。 命令是实现用户与程序之间数据和算法的桥梁。 备注

本文作为MVVM的简单入门示例,旨在抛砖引玉,一起学习,共同进步。如果对WPF的其他入门知识,不是很了解,可以参考其他博文。

玉楼春·别后不知君远近

欧阳修 〔宋代〕

别后不知君远近,触目凄凉多少闷。渐行渐远渐无书,水阔鱼沉何处问。夜深风竹敲秋韵,万叶千声皆是恨。故攲单枕梦中寻,梦又不成灯又烬。注:攲(yǐ)



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭