一、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 和业务逻辑分离,提高了代码的可维护性和可测试性。