WPF的MVVM的基础知识

发布于:2025-03-28 ⋅ 阅读:(28) ⋅ 点赞:(0)

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} 语法或代码来实现。
  • 绑定模式
    • 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 接口来实现命令。
  • 示例
    • 以下是一个简单的命令实现示例:

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 接口来实现属性更改通知。
  • 示例
    • 在前面的 BookViewModel 示例中,BookViewModel 类实现了 INotifyPropertyChanged 接口,当属性值发生变化时,调用 OnPropertyChanged 方法触发 PropertyChanged 事件,通知视图进行更新。

优点

  • 可维护性:将视图和业务逻辑分离,使得代码结构更加清晰,易于维护和扩展。当需要修改视图或业务逻辑时,只需要修改相应的部分,而不会影响到其他部分。
  • 可测试性:视图模型可以独立于视图进行测试,通过模拟数据和命令,可以方便地对视图模型的业务逻辑进行单元测试。
  • 可复用性:视图模型可以在不同的视图中复用,提高了代码的复用性。

总结

MVVM 模式通过将视图和业务逻辑分离,利用数据绑定、命令模式和属性更改通知等特性,提高了代码的可维护性、可测试性和可扩展性。在 WPF 开发中,合理运用 MVVM 模式可以帮助开发者构建高效、可维护的应用程序。