MVVM是WPF中分离UI与业务逻辑的架构模式,由View(XAML界面)、ViewModel(封装逻辑并实现INotifyPropertyChanged和ICommand)和Model(数据与业务)组成,依托数据绑定和命令机制实现解耦。

MVVM(Model-View-ViewModel)是WPF中一种广泛应用的架构模式,旨在分离用户界面逻辑与业务逻辑,提升代码的可维护性、可测试性和可重用性。它的核心在于通过数据绑定和命令机制,让View(视图)与ViewModel(视图模型)解耦。
1. MVVM 的基本结构
View(视图):即XAML页面,负责UI展示和用户交互。它不直接操作数据或逻辑,而是通过绑定依赖属性来显示数据,并通过命令响应用户操作。
ViewModel(视图模型):位于View和Model之间,暴露公共属性和命令供View绑定,封装界面逻辑,比如数据验证、状态管理等。它通常实现 INotifyPropertyChanged 接口以支持数据绑定更新。
Model(模型):代表应用程序的数据和业务逻辑,如实体类、数据访问层等,不关心UI细节。
2. 数据绑定的实现
WPF的数据绑定是MVVM的核心。当ViewModel中的数据发生变化时,View能自动更新,前提是属性触发了通知事件。
实现方式如下:
- ViewModel类实现 INotifyPropertyChanged 接口。
- 在属性的setter中调用 PropertyChanged 事件,通知WPF属性已更改。
public class PersonViewModel : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
在XAML中绑定:
这样,当文本框输入变化时,Name属性会自动更新;反之,代码中修改Name,界面也会刷新。
3. 命令(ICommand)的实现
在MVVM中,按钮点击等操作不能使用传统事件处理(如Click事件),而应通过命令绑定,保持View不包含逻辑代码。
使用 ICommand 接口将动作封装为属性,推荐使用 RelayCommand 或 DelegateCommand 简化实现。
自定义 RelayCommand 示例:
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func _canExecute;
public RelayCommand(Action execute, Func canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute == null || _canExecute();
public void Execute(object parameter) => _execute();
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
在ViewModel中定义命令:
public ICommand SaveCommand { get; private set; }
public PersonViewModel()
{
SaveCommand = new RelayCommand(Save, CanSave);
}
private void Save()
{
// 执行保存逻辑
}
private bool CanSave() => !string.IsNullOrWhiteSpace(Name);
XAML中绑定命令:
此时按钮是否可用会根据 CanSave() 返回值动态更新。
4. 实际应用建议
- 使用NuGet包如 CommunityToolkit.Mvvm(原MvvmHelpers)可简化 ViewModel 基类和命令的编写。
- 避免在View中写后台代码(code-behind),除非必须操作UI元素。
- 合理使用 ObservableCollection
绑定列表数据,确保集合变更也能反映到界面。
基本上就这些。掌握数据绑定和命令机制,就能在WPF中高效使用MVVM模式,写出清晰、易测的界面代码。










