WPF MVVM模式簡介
WPF是Windows Presentation Foundation的縮寫,它是一種用于創(chuàng)建桌面應用程序的用戶界面框架。WPF支持多種開發(fā)模式,其中一種叫做MVVM(Model-View-ViewModel)。
什么是MVVM?
MVVM是一種軟件架構模式,它將應用程序分為三個層次:Model(模型),View(視圖)和ViewModel(視圖模型)。Model表示應用程序的數(shù)據(jù)和業(yè)務邏輯,View表示應用程序的用戶界面,ViewModel表示View和Model之間的橋梁,它負責處理View的數(shù)據(jù)綁定和用戶交互。
為什么要使用MVVM?
使用MVVM有以下幾個好處:
降低了View和Model之間的耦合度,使得它們可以獨立地開發(fā)和測試。
提高了代碼的可重用性和可維護性,因為ViewModel可以在不同的View之間共享。
簡化了單元測試,因為ViewModel不依賴于具體的UI控件。
支持雙向數(shù)據(jù)綁定,使得View可以自動更新Model的變化,反之亦然。
利用了WPF提供的強大特性,如命令、依賴屬性、數(shù)據(jù)注解等。
下圖我們可以直觀的理解MVVM誰急模式:

View: 使用XAML呈現(xiàn)給用戶的界面,負責與用戶交互,接收用戶輸入,把數(shù)據(jù)展現(xiàn)給用戶。
Model: 事物的抽象,開發(fā)過程中涉及到的事物都可以抽象為Model,例如姓名、年齡、性別、地址等屬性.不包含方法,也不需要實現(xiàn)INotifyPropertyChanged接口.
ViewModel: 負責收集需要綁定的數(shù)據(jù)和命令,聚合Model對象,通過View類的DataContext屬性綁定到View。同時也可以處理一些UI邏輯。
如何實現(xiàn)MVVM?
實現(xiàn)MVVM需要遵循以下幾個步驟:
創(chuàng)建一個Model類,定義應用程序所需的數(shù)據(jù)和業(yè)務邏輯。
創(chuàng)建一個ViewModel類,繼承自INotifyPropertyChanged接口,并實現(xiàn)屬性變更通知。在ViewModel中定義與Model相關聯(lián)的屬性,并提供相應的命令來執(zhí)行用戶操作。
創(chuàng)建一個View類(通常是一個XAML文件),定義應用程序的用戶界面。在View中使用數(shù)據(jù)綁定來連接ViewModel中的屬性和命令,并設置相關的樣式和行為。
在App.xaml或其他合適的地方創(chuàng)建一個ViewModel實例,并將其作為View中DataContext屬性值。
示例代碼:
// Model class
public class User
{
? ?public string Name { get; set; }
? ?public int Age { get; set; }
}
// ViewModel class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows;
namespace WpfApp1
{
? ?public class UserInfoViewModel : INotifyPropertyChanged
? ?{
? ? ? ?private User user;
? ? ? ?public UserInfoViewModel()
? ? ? ?{
? ? ? ? ? ?user = new User();
? ? ? ? ? ?SaveCommand = new RelayCommand(Save);
? ? ? ? ? ?CancelCommand = new RelayCommand(Cancel);
? ? ? ?}
? ? ? ?public string UserName
? ? ? ?{
? ? ? ? ? ?get { return user.Name; }
? ? ? ? ? ?set
? ? ? ? ? ?{
? ? ? ? ? ? ? ?user.Name = value;
? ? ? ? ? ? ? ?OnPropertyChanged("UserName");
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?public int UserAge
? ? ? ?{
? ? ? ? ? ?get { return user.Age; }
? ? ? ? ? ?set
? ? ? ? ? ?{
? ? ? ? ? ? ? ?user.Age = value;
? ? ? ? ? ? ? ?OnPropertyChanged("UserAge");
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?public string UserInfo
? ? ? ?{
? ? ? ? ? ?get { return $"Name:{UserName} Age:{UserAge}"; }
? ? ? ?}
? ? ? ?public ICommand SaveCommand { get; private set; }
? ? ? ?public ICommand CancelCommand { get; private set; }
? ? ? ?private void Save(object parameter)
? ? ? ?{
? ? ? ? ? ?// Save user data to database or service
? ? ? ? ? ?MessageBox.Show("User data saved!");
? ? ? ? ? ?OnPropertyChanged("UserInfo");
? ? ? ?}
? ? ? ?private void Cancel(object parameter)
? ? ? ?{
? ? ? ? ? ?// Close dialog window without saving data
? ? ? ? ? ?var window = parameter as Window;
? ? ? ? ? ?if (window != null)
? ? ? ? ? ? ? ?window.Close();
? ? ? ?}
? ? ? ?public event PropertyChangedEventHandler PropertyChanged;
? ? ? ?protected void OnPropertyChanged(string propertyName)
? ? ? ?{
? ? ? ? ? ?if (PropertyChanged != null)
? ? ? ? ? ? ? ?PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
? ? ? ?}
? ?}
}
//Command class
public class RelayCommand : ICommand
{
? ?public RelayCommand(Action<object> action)
? ?{
? ? ? ?DoExecute = action;
? ?}
? ?public event EventHandler? CanExecuteChanged;
? ?public Func<object, bool>? CanExecution { set; get; }
? ?public Action<object>? DoExecute { set; get; }
? ?public bool CanExecute(object? parameter)
? ?{
? ? ? ?if (CanExecution != null)
? ? ? ?{
? ? ? ? ? ?CanExecute(parameter);
? ? ? ?}
? ? ? ?return true;
? ?}
? ?public void Execute(object? parameter)
? ?{
? ? ? ?DoExecute!.Invoke(parameter!);
? ?}
}
// View class (XAML file)
<Window x:Class="WpfApp1.MainWindow"
? ? ? ?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
? ? ? ?xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
? ? ? ?Title="MainWindow" Height="220" Width="300">
? ?<Grid>
? ? ? ?<Grid.RowDefinitions>
? ? ? ? ? ?<RowDefinition Height="Auto"/>
? ? ? ? ? ?<RowDefinition Height="Auto"/>
? ? ? ? ? ?<RowDefinition Height="Auto"/>
? ? ? ? ? ?<RowDefinition Height="*"/>
? ? ? ?</Grid.RowDefinitions>
? ? ? ?<Grid.ColumnDefinitions>
? ? ? ? ? ?<ColumnDefinition Width="Auto"/>
? ? ? ? ? ?<ColumnDefinition Width="*"/>
? ? ? ?</Grid.ColumnDefinitions>
? ? ? ?<!-- Labels and textboxes for user name and age -->
? ? ? ?<Label Content="Name:" Grid.Row="0" Grid.Column="0" Margin="10"/>
? ? ? ?<TextBox Text="{Binding UserName}" Grid.Row="0" Grid.Column="1" Margin="10"/>
? ? ? ?<Label Content="Age:" Grid.Row="1" Grid.Column="0" Margin="10"/>
? ? ? ?<TextBox Text="{Binding UserAge}" Grid.Row="1" Grid.Column="1" Margin="10"/>
? ? ? ?<Label Content="{Binding UserInfo}" Grid.Row="2" Grid.Column="1" Margin="10"/>
? ? ? ?<!-- Buttons for save and cancel commands -->
? ? ? ?<StackPanel Orientation= "Horizontal" HorizontalAlignment= "Right"
? ? ? ? ? ? ? ? ? ?Grid.Row= "3" Grid.ColumnSpan= "2">
? ? ? ? ? ?<Button Content= "Save" Command="{Binding SaveCommand}"
? ? ? ? ? ? ? ? ? ?CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,
? ? ? ? ? ? ? ? ?AncestorType={x:Type Window}}}" Margin= "10"/>
? ? ? ? ? ?<Button Content= "Cancel" Command="{Binding CancelCommand}"
? ? ? ? ? ? ? ? ? ?CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,
? ? ? ? ? ? ? ? ?AncestorType={x:Type Window}}}" Margin= "10"/>
? ? ? ?</StackPanel>
? ?</Grid>
</Window>
// View code-behind file
using System.Windows;
namespace WpfApp1
{
? /// Interaction logic for UserInfoView.xaml
? public partial class MainWindow : Window
? {
? ? ?public MainWindow()
? ? ?{
? ? ? ? InitializeComponent();
? ? ? ? // Set the ViewModel as the DataContext of the View
? ? ? ? this.DataContext = new UserInfoViewModel();
? ? ?}
? }
}
運行結果如下:

代碼位置:https://github.com/DXG88/WpfApp1.git
有哪些MVVM框架?
雖然可以手動實現(xiàn)MVVM模式,但是也有許多第三方庫提供了更方便和高效地使用MVVM模式。以下是一些常見且流行的MVVM框架:
Prism: 一個由微軟支持的MVVM框架,提供了一系列服務和特性,如導航、模塊化、事件聚合、命令、依賴注入等。
MVVM Light: 一個輕量級的MVVM框架,提供了一些基礎類和組件,如ViewModelBase, RelayCommand, Messenger等。
Caliburn.Micro: 一個基于約定而非配置的MVVM框架,提供了一些高級特性,如屏幕激活/關閉生命周期管理、自動綁定、窗口管理器等。
原文地址:WPF MVVM模式簡介 - 百寶門的博客 (baibaomen.com)