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

相关推荐
UXbot28 分钟前
原型设计工具如何帮助新人快速进入产品行业?
前端·低代码·ui·交互·团队开发·原型模式·web app
烈焰晴天4 小时前
Codex 桌面端如何链接Figma MCP 服务器拿到 Figma设计稿精准尺寸等结构化数据 来精准还原UI
服务器·ui·figma
狼哥16868 小时前
防沉迷控制实战新特性接入
ui·华为·harmonyos
狼哥168611 小时前
学习卡片案例新特性接入
ui·华为·harmonyos
zdr尽职尽责12 小时前
Unity录像功能
学习·ui·unity·游戏引擎
山东布谷网络科技12 小时前
海外直播语聊APP功能与UI升级的关键关注点
开发语言·ui·app store·谷歌上架·海外直播app开发·海外语聊平台搭建·多语言直播平台定制
鹤卿1231 天前
(OC)UI学习——网易云仿写
ui·ios·objective-c
一个被程序员耽误的厨师1 天前
04-实践篇-让AI生成可视化页面-ai-json-ui的落地实践
人工智能·ui·json
秋雨梧桐叶落莳1 天前
iOS——QQ音乐仿写项目总结
学习·macos·ui·ios·mvc·objective-c·xcode
俏皮小混子2 天前
山东大学软件学院项目实训-创新实训-计科智伴(六)——个人博客(后端运行后真实调整)
人工智能·笔记·学习·ui