编辑
2025-11-25
C#
00

目录

什么是 INotifyPropertyChanged 接口
手动实现 INotifyPropertyChanged
示例:WinForms 应用程序
优点和缺点
使用 CommunityToolkit.Mvvm 简化实现
安装 NuGet 包
示例:使用 ObservableObject
示例:使用 [ObservableProperty] 属性
编译后的自动生成代码
完整示例
总结

在 C# 开发中,INotifyPropertyChanged 接口在实现 MVVM(Model-View-ViewModel)模式时至关重要。它允许视图(UI)在后台数据发生变化时自动更新,从而实现数据绑定和界面同步。本文将详细介绍如何实现 INotifyPropertyChanged 接口,并利用 CommunityToolkit.Mvvm 库简化开发过程。

什么是 INotifyPropertyChanged 接口

INotifyPropertyChanged 是位于 System.ComponentModel 命名空间中的一个接口,主要用于通知绑定客户端属性值已更改。它包含一个事件:

C#
public event PropertyChangedEventHandler PropertyChanged;

当属性值发生变化时,需要触发 PropertyChanged 事件,通知绑定的 UI 更新显示。

手动实现 INotifyPropertyChanged

示例:WinForms 应用程序

下面是一个手动实现 INotifyPropertyChanged 的示例。在 WinForms 应用程序中,我们创建一个 Person 类,实现 INotifyPropertyChanged 接口。

C#
using System; using System.ComponentModel; public class Person : INotifyPropertyChanged { private string name; private int age; public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public string Name { get => name; set { if (name != value) { name = value; OnPropertyChanged(nameof(Name)); } } } public int Age { get => age; set { if (age != value) { age = value; OnPropertyChanged(nameof(Age)); } } } }
C#
using System.ComponentModel; namespace App03 { internal class Program { static void Main(string[] args) { // 创建 Person 实例 Person person = new Person(); // 添加属性变更事件处理程序 person.PropertyChanged += Person_PropertyChanged; // 修改属性值,触发属性变更事件 Console.WriteLine("设置姓名和年龄:"); person.Name = "张三"; person.Age = 25; Console.WriteLine("\n当前人员信息:"); Console.WriteLine($"姓名: {person.Name}"); Console.WriteLine($"年龄: {person.Age}"); Console.WriteLine("\n修改年龄:"); person.Age = 26; Console.WriteLine("\n重复设置相同的姓名(不会触发事件):"); person.Name = "张三"; Console.WriteLine("\n修改姓名:"); person.Name = "李四"; } // 属性变更事件处理程序 private static void Person_PropertyChanged(object sender, PropertyChangedEventArgs e) { Console.WriteLine($"属性已更改: {e.PropertyName}"); // 获取更改后的值 Person person = sender as Person; switch (e.PropertyName) { case nameof(Person.Name): Console.WriteLine($"新的姓名值: {person.Name}"); break; case nameof(Person.Age): Console.WriteLine($"新的年龄值: {person.Age}"); break; } } } }

image.png

在这个示例中,我们手动实现了 OnPropertyChanged 方法,并在属性的 set 访问器中调用它。每当属性值改变时,都会触发 PropertyChanged 事件。

优点和缺点

手动实现虽然直观,但当属性较多时,需要重复大量的代码,容易出错且不便于维护。

使用 CommunityToolkit.Mvvm 简化实现

CommunityToolkit.Mvvm(原名 Microsoft.Toolkit.Mvvm)是微软提供的开源 MVVM 工具包,简化了 MVVM 模式下的常见任务。它提供了属性更改通知的自动化,实现了更简洁的代码。

安装 NuGet 包

首先,通过 NuGet 包管理器安装 CommunityToolkit.Mvvm

Bash
Install-Package CommunityToolkit.Mvvm

示例:使用 ObservableObject

ObservableObjectCommunityToolkit.Mvvm 提供的一个基类,实现了 INotifyPropertyChanged 接口。

C#
using CommunityToolkit.Mvvm.ComponentModel; public class Person : ObservableObject { private string name; private int age; public string Name { get => name; set => SetProperty(ref name, value); } public int Age { get => age; set => SetProperty(ref age, value); } }

在这个示例中,我们继承了 ObservableObject,并使用 SetProperty 方法来设置属性值和通知更改。

示例:使用 [ObservableProperty] 属性

CommunityToolkit.Mvvm 还提供了属性变化的源生成器,使用 [ObservableProperty] 属性自动生成代码。

C#
using CommunityToolkit.Mvvm.ComponentModel; public partial class Person : ObservableObject { [ObservableProperty] private string name; [ObservableProperty] private int age; }

通过在字段前添加 [ObservableProperty],源生成器会自动生成对应的属性和通知代码。需要将类声明为 partial

编译后的自动生成代码

实际编译后,源生成器会生成如下代码:

C#
public string Name { get => name; set => SetProperty(ref name, value); } public int Age { get => age; set => SetProperty(ref age, value); }

完整示例

以下是一个完整的 WinForms 应用程序示例,演示如何使用 Person 类并绑定到 UI 控件。

C#
public partial class Person : ObservableObject { [ObservableProperty] private string name; [ObservableProperty] private int age; }
C#
public partial class Form1 : Form { private Person person; public Form1() { InitializeComponent(); person = new Person { Name = "张三", Age = 30 }; txtName.DataBindings.Add("Text", person, "Name", false, DataSourceUpdateMode.OnPropertyChanged); nuAge.DataBindings.Add("Value", person, "Age", false, DataSourceUpdateMode.OnPropertyChanged); } }

image.png

总结

使用 CommunityToolkit.Mvvm 能够大大简化 INotifyPropertyChanged 接口的实现,减少样板代码,提高开发效率。通过源生成器 [ObservableProperty],我们可以专注于业务逻辑,而不必手动编写重复的属性更改通知代码。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!