前言
前幾天學習了劉鐵猛老師的《深入淺出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代碼

解決方案文件結構
在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/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。