前言
前几天学习了刘铁猛老师的《深入浅出WPF》之MVVM入门与提高教程,仿照教程,用VS2019、Blend SDK和Prism框架创建了简单的MVVM设计模式的程序。
学习/开发环境
- Microsoft Visual Studio 2019
- Microsoft Prism
- Microsoft Blend SDK
必要的知识准备
- 熟悉Data Binding和Dependency Property
- 了解WPF中的命令(ICommand接口)
- 熟悉Lambda表达式
MVVM设计模式详解
- MVVM = Model + View + ViewModel
- 为什么要使用MVVM
- 团队层面: 统一思维方式和实现方法
- 架构层面:稳定、解耦
- 代码层面:易读、易测、易替换
- 什么是Model
- 现实世界中对象的抽象结果
- 什么是View和ViewModel
- View = UI
- ViewModel = View For Model
- ViewModel与View的沟通
- 传递数据 - 数据属性
- 传递命名 - 命令属性
创建WPF项目和NuGet方式添加Blend SDK和Prism框架
创建解决方案并添加Wpf应用程序
NuGet添加
- Expression.Blend.Sdk.WPF
- Prism.Wpf
主界面xaml代码
MainWindow.xaml
解决方案文件结构
在Commands文件夹下创建DelegateCommand对象
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace WpfDemo.Commands { class DelegateCommand : ICommand { public event EventHandler CanExecuteChanged; /// <summary> /// 判断命令是否可以执行 /// </summary> /// <param name="parameter"></param> /// <returns></returns> public bool CanExecute(object parameter) { if (this.CanExecuteFunc != null) { this.CanExecuteFunc(parameter); } else { return true; } return false; } /// <summary> /// 执行相关的命令 /// </summary> /// <param name="parameter">相关命令</param> public void Execute(object parameter) { if (this.ExecuteAction == null) { return; } this.ExecuteAction(parameter); } /// <summary> /// 声明一个委托用来执行命令对应的方法 /// </summary> public Action<object> ExecuteAction { get; set; } /// <summary> /// 声明一个方法,用来判断命令是否可以被执行 /// </summary> public Func<object, bool> CanExecuteFunc { get; set; } } }
在ViewModels文件夹下分别创建NotificationObject和MainWindowViewModel对象
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfDemo.ViewModels { //继承负责通知View的接口 class NotificationObject : INotifyPropertyChanged { // 接口的实现 public event PropertyChangedEventHandler PropertyChanged; // 封装一个方法用来通知 public void RaisePropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } }
using Microsoft.Win32; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WpfDemo.Commands; namespace WpfDemo.ViewModels { class MainWindowViewModel : NotificationObject { /// <summary> /// 数据属性 /// 输入值1 /// </summary> private double input1; public double Input1 { get { return input1; } set { input1 = value; this.RaisePropertyChanged("Input1"); } } /// <summary> /// 数据属性 /// 输入值2 /// </summary> private double input2; public double Input2 { get { return input2; } set { input2 = value; this.RaisePropertyChanged("Input2"); } } /// <summary> /// 数据属性 /// 返回值1 /// </summary> private double result; public double Result { get { return result; } set { result = value; this.RaisePropertyChanged("Result"); } } public DelegateCommand AddCommand { get; set; } public DelegateCommand SaveCommand { get; set; } /// <summary> /// 加法运算 /// </summary> /// <param name="parameter"></param> private void Add(object parameter) { this.Result = this.Input2 + this.Input1; } /// <summary> /// 打开保存对话框 /// </summary> /// <param name="parameter"></param> private void Save(object parameter) { SaveFileDialog sfd = new SaveFileDialog(); sfd.ShowDialog(); } public MainWindowViewModel() { // 让Add和AddCommand关联起来 this.AddCommand = new DelegateCommand(); this.AddCommand.ExecuteAction = new Action<object>(this.Add); // 让Save和SaveCommand关联起来 this.SaveCommand = new DelegateCommand(); this.SaveCommand.ExecuteAction = new Action<object>(this.Save); } } }
输入框绑定数据属性、按钮绑定命令属性
<TextBox Text="{Binding Input1}" Grid.Row="0" /> <TextBox Text="{Binding Input2}" Grid.Row="1" /> <TextBox Text="{Binding Result}" Grid.Row="2" /> <Button Command="{Binding AddCommand}" Grid.Row="3" Content="Plus"/> <Button Command="{Binding SaveCommand}" Grid.Row="3" Content="Save"/>
注意:绑定内容要与ViewModel中的属性名一致;
最后,建立DataContext指向MainWindowViewModel,即this.DataContext = new MainWindowViewModel();
作者:Jeremy.Wu
出处:https://www.cnblogs.com/jeremywucnblog/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。