WPF中的MVVM框架

一、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 示例:

  1. 定义了 Model(Person 类)。

  2. 创建了 ViewModel(MainViewModel 类),实现了 INotifyPropertyChanged 和命令。

  3. 定义了 View(XAML 文件),并通过数据绑定与 ViewModel 交互。

  4. 使用命令处理用户操作。

这种模式将 UI 和业务逻辑分离,提高了代码的可维护性和可测试性。

相关推荐
修炼前端秘籍的小帅5 天前
Stitch——Google热门的免费AI UI设计工具
前端·人工智能·ui
王码码20355 天前
Flutter for OpenHarmony:socket_io_client 实时通信的事实标准(Node.js 后端的最佳拍档) 深度解析与鸿蒙适配指南
android·flutter·ui·华为·node.js·harmonyos
2501_921930835 天前
Flutter for OpenHarmony:第三方库实战 chewie 视频播放器UI组件详解
flutter·ui
梵得儿SHI5 天前
Vue3 生态工具实战宝典:UI 组件库 + 表单验证全解析(Element Plus/Ant Design Vue/VeeValidate)
前端·vue.js·ui·elementplus·vue性能优化·antdesignvue·表单验证方案
Unity游戏资源学习屋5 天前
【Unity UI资源包】GUI Pro - Casual Game 专为休闲手游打造的专业级UI资源包
ui·unity
麻瓜呀6 天前
vue2 Element-ui框架相关常见问题-表单组件重置显示异常
运维·服务器·ui
少云清6 天前
【UI自动化测试】4_PO模式 _PO模式封装
ui·po模式
菜鸟小芯6 天前
【GLM-5 陪练式创意 UI 实战】第二篇:创意魔法盒 —— 从 “开心” 到 “科技感”,AI 驱动的 UI 风格迭代
科技·ui