一、MVVM 模式的核心概念
1. Model(模型)
表示应用程序的数据模型,通常是一个简单的类,包含数据属性和业务逻辑。
不依赖于 UI,可以独立于 WPF 使用。
2. View(视图)
是用户界面,通常由 XAML 文件定义。
通过数据绑定与 ViewModel 交互,不直接与 Model 交互。
3. ViewModel(视图模型)
是 Model 和 View 之间的中间层,负责处理业务逻辑和用户交互。
提供数据绑定的接口(通常是
INotifyPropertyChanged
),并将 Model 的数据暴露给 View。可以包含命令(
ICommand
)来处理用户的操作。
二、实现步骤
1. 定义 Model
Model 是一个简单的类,包含数据属性和业务逻辑。例如,定义一个 Person
类:
public class Person { public string Name { get; set; } public int Age { get; set; } }
2. 创建 ViewModel
ViewModel 是 MVVM 的核心,它需要实现 INotifyPropertyChanged
接口,以便通知 View 数据的变化。同时,ViewModel 会包含 Model 的实例,并提供绑定到 View 的属性。
实现 INotifyPropertyChanged
using System.ComponentModel; using System.Runtime.CompilerServices; public class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
创建具体的 ViewModel
public class MainViewModel : ViewModelBase { private Person _person; public MainViewModel() { // 初始化 Model _person = new Person { Name = "John Doe", Age = 30 }; } // 提供绑定到 View 的属性 public string Name { get => _person.Name; set { if (_person.Name != value) { _person.Name = value; OnPropertyChanged(); } } } public int Age { get => _person.Age; set { if (_person.Age != value) { _person.Age = value; OnPropertyChanged(); } } } }
3. 创建 View
View 是 XAML 文件,通过数据绑定与 ViewModel 交互。在 XAML 中,需要设置 DataContext
,并将控件的属性绑定到 ViewModel 的属性。
定义 XAML 文件
<Window x:Class="WpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MVVM Example" Height="200" Width="300"> <Grid> <StackPanel Margin="10"> <TextBlock Text="Name:" /> <TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <TextBlock Text="Age:" /> <TextBox Text="{Binding Age, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <Button Content="Save" Command="{Binding SaveCommand}" Margin="0,10,0,0" /> </StackPanel> </Grid> </Window>
设置 DataContext
在代码后台(MainWindow.xaml.cs
)中,设置 DataContext
为 ViewModel 的实例:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new MainViewModel(); } }
4. 实现命令(Command)
在 MVVM 中,按钮的点击事件通常通过命令(ICommand
)来处理。可以在 ViewModel 中定义一个命令属性。
定义命令类
using System; using System.Windows.Input; public class RelayCommand : ICommand { private readonly Action _execute; private readonly Func<bool> _canExecute; public RelayCommand(Action execute, Func<bool> canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute == null || _canExecute(); } public void Execute(object parameter) { _execute(); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } }
在 ViewModel 中使用命令
public class MainViewModel : ViewModelBase { private Person _person; public MainViewModel() { _person = new Person { Name = "John Doe", Age = 30 }; } public string Name { get => _person.Name; set { if (_person.Name != value) { _person.Name = value; OnPropertyChanged(); } } } public int Age { get => _person.Age; set { if (_person.Age != value) { _person.Age = value; OnPropertyChanged(); } } } // 定义命令 public ICommand SaveCommand { get; } public MainViewModel() { _person = new Person { Name = "John Doe", Age = 30 }; SaveCommand = new RelayCommand(Save); } private void Save() { // 处理保存逻辑 MessageBox.Show("Data saved!"); } }
5. 完整的绑定
在 XAML 中绑定命令:
<Button Content="Save" Command="{Binding SaveCommand}" Margin="0,10,0,0" />
三、总结
通过以上步骤,我们实现了一个简单的 MVVM 示例:
定义了 Model(
Person
类)。创建了 ViewModel(
MainViewModel
类),实现了INotifyPropertyChanged
和命令。定义了 View(XAML 文件),并通过数据绑定与 ViewModel 交互。
使用命令处理用户操作。
这种模式将 UI 和业务逻辑分离,提高了代码的可维护性和可测试性。