WPF的MVVM的基础知识
MVVM 概述
MVVM(Model - View - ViewModel)是一种用于构建用户界面的软件设计模式,特别适用于 WPF(Windows Presentation Foundation)、Silverlight、UWP(Universal Windows Platform)等基于 XAML 的技术。该模式旨在将视图(用户界面)和业务逻辑分离,从而提高代码的可维护性、可测试性和可扩展性。
核心组件详解
1. 模型(Model)
- 定义与作用 
  - 模型代表应用程序的数据和业务逻辑。它是应用程序的核心数据结构和处理规则的集合,负责与数据库、网络服务、文件系统等数据源进行交互,实现数据的存储、检索、更新和删除等操作。模型不依赖于视图和视图模型,它是独立于用户界面的。
 
- 示例 
  - 以一个简单的图书管理系统为例,Book类可以作为模型,它包含了图书的基本信息,如书名、作者、ISBN 等,同时还可以包含一些与图书数据相关的操作方法,如验证 ISBN 的有效性。
 
- 以一个简单的图书管理系统为例,
csharp
public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
    public string ISBN { get; set; }
    public Book(string title, string author, string isbn)
    {
        Title = title;
        Author = author;
        ISBN = isbn;
    }
    public bool IsValidISBN()
    {
        // 简单的 ISBN 验证逻辑
        return !string.IsNullOrEmpty(ISBN) && ISBN.Length == 13;
    }
}
2. 视图(View)
- 定义与作用 
  - 视图是用户界面的可视化呈现,负责展示数据和接收用户的输入。在 WPF 中,视图通常由 XAML 文件定义,XAML 是一种声明式的标记语言,用于描述界面的布局、样式和交互元素。视图只关注界面的外观和用户交互,不包含任何业务逻辑。
 
- 示例 
  - 以下是一个简单的 WPF 视图示例,用于显示图书信息:
 
xml
<Window x:Class="BookManagementSystem.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Book Management System" Height="350" Width="525">
    <Grid>
        <TextBlock Text="{Binding Title}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <TextBlock Text="{Binding Author}" HorizontalAlignment="Left" Margin="10,30,0,0" VerticalAlignment="Top"/>
        <TextBlock Text="{Binding ISBN}" HorizontalAlignment="Left" Margin="10,50,0,0" VerticalAlignment="Top"/>
    </Grid>
</Window>
- 在这个示例中,TextBlock控件用于显示图书的标题、作者和 ISBN 信息,通过{Binding}语法将这些控件的Text属性绑定到视图模型的相应属性上。
3. 视图模型(ViewModel)
- 定义与作用 
  - 视图模型是视图和模型之间的桥梁,负责处理视图的逻辑和数据绑定。它包含了视图所需的数据和命令,将模型的数据转换为视图可以展示的格式,并处理用户在视图上的操作。视图模型实现了视图和模型之间的解耦,使得视图和模型可以独立开发和测试。
 
- 示例 
  - 以下是一个简单的图书管理系统的视图模型示例:
 
csharp
using System.ComponentModel;
public class BookViewModel : INotifyPropertyChanged
{
    private Book _book;
    public string Title
    {
        get { return _book.Title; }
        set
        {
            if (_book.Title != value)
            {
                _book.Title = value;
                OnPropertyChanged(nameof(Title));
            }
        }
    }
    public string Author
    {
        get { return _book.Author; }
        set
        {
            if (_book.Author != value)
            {
                _book.Author = value;
                OnPropertyChanged(nameof(Author));
            }
        }
    }
    public string ISBN
    {
        get { return _book.ISBN; }
        set
        {
            if (_book.ISBN != value)
            {
                _book.ISBN = value;
                OnPropertyChanged(nameof(ISBN));
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public BookViewModel(Book book)
    {
        _book = book;
    }
}
- 在这个示例中,BookViewModel类实现了INotifyPropertyChanged接口,用于实现属性更改通知。当视图模型的属性值发生变化时,会触发PropertyChanged事件,通知视图进行更新。
关键特性详解
1. 数据绑定
- 定义与作用 
  - 数据绑定是 MVVM 模式的核心特性之一,它允许视图和视图模型之间建立动态的连接,使得视图能够自动反映视图模型中数据的变化,同时也能将用户在视图上的输入传递给视图模型。在 WPF 中,数据绑定可以通过 XAML 中的 {Binding}语法或代码来实现。
 
- 数据绑定是 MVVM 模式的核心特性之一,它允许视图和视图模型之间建立动态的连接,使得视图能够自动反映视图模型中数据的变化,同时也能将用户在视图上的输入传递给视图模型。在 WPF 中,数据绑定可以通过 XAML 中的 
- 绑定模式 
  - OneWay:数据从视图模型流向视图,当视图模型的属性值发生变化时,视图会自动更新。这是最常用的绑定模式,适用于只读属性的绑定。
- TwoWay:数据可以在视图和视图模型之间双向流动,当视图模型的属性值发生变化时,视图会更新;当用户在视图上输入数据时,视图模型的属性值也会更新。适用于可编辑的文本框、复选框等控件的绑定。
- OneTime:数据仅在绑定初始化时从视图模型流向视图,之后视图模型的属性值变化不会影响视图。适用于不需要实时更新的静态数据的绑定。
 
- 示例 
  - 以下是一个使用 TwoWay绑定模式的示例,将一个TextBox控件的Text属性绑定到视图模型的Title属性上:
 
- 以下是一个使用 
xml
<TextBox Text="{Binding Title, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="200"/>
2. 命令模式
- 定义与作用 
  - 命令模式是 MVVM 模式中处理用户交互的一种方式,它将用户的操作封装成命令对象,使得视图模型能够处理用户在视图上的操作。在 WPF 中,通常使用 ICommand接口来实现命令。
 
- 命令模式是 MVVM 模式中处理用户交互的一种方式,它将用户的操作封装成命令对象,使得视图模型能够处理用户在视图上的操作。在 WPF 中,通常使用 
- 示例 
  - 以下是一个简单的命令实现示例:
 
csharp
using System;
using System.Windows.Input;
public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;
    public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute(parameter);
    }
    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}
- 在视图模型中使用该命令:
csharp
public class BookViewModel
{
    public ICommand SaveCommand { get; set; }
    public BookViewModel()
    {
        SaveCommand = new RelayCommand(SaveBook);
    }
    private void SaveBook(object parameter)
    {
        // 保存图书数据的逻辑
    }
}
- 在视图中绑定命令:
xml
<Button Content="Save" Command="{Binding SaveCommand}" HorizontalAlignment="Left" Margin="10,100,0,0" VerticalAlignment="Top"/>
3. 属性更改通知
- 定义与作用 
  - 在 MVVM 模式中,当视图模型的属性值发生变化时,需要通知视图进行更新。在 WPF 中,通常通过实现 INotifyPropertyChanged接口来实现属性更改通知。
 
- 在 MVVM 模式中,当视图模型的属性值发生变化时,需要通知视图进行更新。在 WPF 中,通常通过实现 
- 示例 
  - 在前面的 BookViewModel示例中,BookViewModel类实现了INotifyPropertyChanged接口,当属性值发生变化时,调用OnPropertyChanged方法触发PropertyChanged事件,通知视图进行更新。
 
- 在前面的 
优点
- 可维护性:将视图和业务逻辑分离,使得代码结构更加清晰,易于维护和扩展。当需要修改视图或业务逻辑时,只需要修改相应的部分,而不会影响到其他部分。
- 可测试性:视图模型可以独立于视图进行测试,通过模拟数据和命令,可以方便地对视图模型的业务逻辑进行单元测试。
- 可复用性:视图模型可以在不同的视图中复用,提高了代码的复用性。
总结
MVVM 模式通过将视图和业务逻辑分离,利用数据绑定、命令模式和属性更改通知等特性,提高了代码的可维护性、可测试性和可扩展性。在 WPF 开发中,合理运用 MVVM 模式可以帮助开发者构建高效、可维护的应用程序。
