C# WPF入门学习主线篇(三十)—— MVVM(Model-View-ViewModel)模式
MVVM(Model-View-ViewModel)模式是WPF(Windows Presentation Foundation)开发中的一种常用架构模式。它通过将用户界面(View)与业务逻辑和数据(Model)分离开来,提高了代码的可维护性和可测试性。本文将详细介绍MVVM模式的基本概念和实现方法,并通过一个示例演示如何在WPF应用程序中使用MVVM模式。
一、MVVM模式的基本概念
1. Model
Model
表示应用程序的核心数据和业务逻辑。它通常包含数据结构、业务规则和数据访问代码。在MVVM模式中,Model不依赖于UI,它是独立的可重用组件。
2. View
View
表示用户界面,它负责显示数据和接收用户输入。View通过数据绑定和命令与ViewModel交互,而不直接访问Model。View通常是XAML文件及其相关的代码隐藏文件。
3. ViewModel
ViewModel
是View和Model之间的桥梁。它负责从Model获取数据,并将这些数据提供给View,同时处理用户在View上的交互。ViewModel通常实现通知机制(如INotifyPropertyChanged接口),以便在数据变化时通知View进行更新。
二、MVVM模式的实现
接下来,我们通过一个简单的示例演示如何在WPF应用程序中实现MVVM模式。
1. 定义Model
首先,我们定义一个简单的Model类Person
,包含两个属性Name
和Age
。
public class Person
{public string Name { get; set; }public int Age { get; set; }
}
2. 定义ViewModel
接下来,我们定义ViewModel类PersonViewModel
,实现INotifyPropertyChanged接口,以便在属性变化时通知View。
using System.ComponentModel;public class PersonViewModel : INotifyPropertyChanged
{private Person _person;public PersonViewModel(){_person = new Person { Name = "John Doe", Age = 30 };}public string Name{get => _person.Name;set{if (_person.Name != value){_person.Name = value;OnPropertyChanged("Name");}}}public int Age{get => _person.Age;set{if (_person.Age != value){_person.Age = value;OnPropertyChanged("Age");}}}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}
3. 定义View
然后,我们定义View,使用XAML文件和数据绑定将UI控件绑定到ViewModel的属性。
<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 Demo" Height="200" Width="300"><Grid><StackPanel><TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" FontSize="16" Margin="10"/><TextBox Text="{Binding Age, UpdateSourceTrigger=PropertyChanged}" FontSize="16" Margin="10"/></StackPanel></Grid>
</Window>
4. 在MainWindow中绑定ViewModel
最后,我们在MainWindow的构造函数中创建PersonViewModel实例,并将其设置为DataContext。
using System.Windows;namespace WpfApp
{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();this.DataContext = new PersonViewModel();}}
}
三、实现命令绑定
在MVVM模式中,我们通常使用命令来处理用户的交互,而不是直接在View中处理事件。下面我们演示如何在ViewModel中实现命令绑定。
1. 定义RelayCommand类
我们定义一个通用的命令类RelayCommand
,实现ICommand接口。
using System;
using System.Windows.Input;public class RelayCommand : ICommand
{private readonly Action<object> _execute;private readonly Func<object, bool> _canExecute;public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null){_execute = execute;_canExecute = canExecute;}public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);public void Execute(object parameter) => _execute(parameter);public event EventHandler CanExecuteChanged{add => CommandManager.RequerySuggested += value;remove => CommandManager.RequerySuggested -= value;}
}
2. 在ViewModel中定义命令
在ViewModel中定义命令并实现命令的逻辑。
public class PersonViewModel : INotifyPropertyChanged
{private Person _person;public PersonViewModel(){_person = new Person { Name = "John Doe", Age = 30 };UpdateCommand = new RelayCommand(UpdatePerson);}public string Name{get => _person.Name;set{if (_person.Name != value){_person.Name = value;OnPropertyChanged("Name");}}}public int Age{get => _person.Age;set{if (_person.Age != value){_person.Age = value;OnPropertyChanged("Age");}}}public ICommand UpdateCommand { get; }private void UpdatePerson(object parameter){Name = "Updated Name";Age = 35;}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}
3. 在View中绑定命令
在View中添加一个按钮,并将其命令属性绑定到ViewModel中的命令。
<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 Demo" Height="200" Width="300"><Grid><StackPanel><TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" FontSize="16" Margin="10"/><TextBox Text="{Binding Age, UpdateSourceTrigger=PropertyChanged}" FontSize="16" Margin="10"/><Button Content="Update" Command="{Binding UpdateCommand}" FontSize="16" Margin="10"/></StackPanel></Grid>
</Window>
四、总结
在本篇文章中,我们介绍了MVVM模式的基本概念,并通过一个简单的示例演示了如何在WPF应用程序中实现MVVM模式。我们详细讲解了Model、View和ViewModel的定义和实现,以及如何通过数据绑定和命令绑定实现UI和业务逻辑的分离。
通过MVVM模式,我们可以将业务逻辑和数据与UI分离,从而提高代码的可维护性、可测试性和可重用性。希望本文能帮助你更好地理解和应用MVVM模式,提高WPF开发的效率和质量。