WPF 彻底搞懂 INotifyPropertyChanged

【WPF】 数据绑定机制之INotifyPropertyChanged (Microsoft.Toolkit.Mvvm)是 Microsoft 推出的 MVVM 框架,它在。它的主要作用是,当对象的某个属性值发生更改时,通知绑定到该属性的 UI 控件更新其显示内容。操作符替代硬编码的字符串,避免因属性名变更导致的问题。: 如果一个属性的更改会影响其他属性,可以触发多个。层,确保当属性值更改时,UI 会自动更新。是 WPF 中的一个接口,用于实现。创建一个简单的 WPF 界面,绑定到。当某个属性的值发生变化时,通常由。,通知所有属性值发生变化。在 MVVM 模式中, 阅读详情

在 WPF 开发中,只要用到数据绑定,就绕不开一个核心接口:INotifyPropertyChanged。
它是实现“ViewModel 属性变化 → UI 自动更新”的基石,也是 MVVM 架构的灵魂。

一、为什么要用 INotifyPropertyChanged?

WPF 数据绑定默认是一次性绑定:
界面加载时,ViewModel 的值会同步到控件;
但属性后续变化,UI 不会自动刷新。

比如:

public string Name { get; set; }

你在代码里改 Name = "新值",界面 TextBox 不会变。

原因很简单:
UI 不知道属性变了。

而 INotifyPropertyChanged 的作用就是:
当属性值改变时,主动通知 UI 去更新。


二、接口定义

它位于 System.ComponentModel 命名空间,结构非常简单:

namespace System.ComponentModel
{
    /// <summary>
    /// 通知客户端:属性值已发生变化
    /// (WPF绑定自动更新UI的核心接口)
    /// </summary>
    public interface INotifyPropertyChanged
    {
        /// <summary>
        /// 属性值改变时触发的事件
        /// UI会监听此事件自动刷新
        /// </summary>
        event PropertyChangedEventHandler? PropertyChanged;
    }
}

只有一个事件:

  • PropertyChanged:属性变化时触发,告诉绑定引擎更新界面。

三、最基础实现

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace _00022.WPF_彻底搞懂_INotifyPropertyChanged.Core
{
    /// <summary>
    /// ViewModel 基类
    /// 实现 INotifyPropertyChanged 接口,用于WPF绑定属性通知
    /// 所有页面ViewModel都可以继承这个基类
    /// </summary>
    public class ViewModelBase : INotifyPropertyChanged
    {
        /// <summary>
        /// 属性变更事件(WPF绑定系统会监听这个事件)
        /// </summary>
        public event PropertyChangedEventHandler? PropertyChanged;

        /// <summary>
        /// 触发属性变更通知
        /// [CallerMemberName]:自动获取调用该方法的属性名,不用手动传参
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            // 如果有订阅者,就触发属性变更事件
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// 通用属性赋值方法
        /// 作用:判断新值是否与旧值相同,不同才赋值并触发通知
        /// 避免重复触发UI刷新,提升性能
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="field">后台私有字段</param>
        /// <param name="value">新值</param>
        /// <param name="propertyName">属性名(自动获取)</param>
        /// <returns>是否发生了值变更</returns>
        protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            // 如果新旧值相等,直接返回不做处理
            if (EqualityComparer<T>.Default.Equals(field, value))
                return false;

            // 更新字段值
            field = value;
            // 触发属性变更通知
            OnPropertyChanged(propertyName);
            return true;
        }

        // 导航命令、加载命令、全局命令可放这里

        /// <summary>
        /// 初始化方法(可重写)
        /// </summary>
        public virtual void Init() { }

        /// <summary>
        /// 清理数据方法(可重写)
        /// </summary>
        public virtual void Clear() { }
    }
}
关键点
  1. [CallerMemberName]
    编译器自动帮你填属性名,不用手写字符串,避免写错。

  2. 必须在属性 set 中调用 OnPropertyChanged()
    否则 UI 收不到通知。


四、进阶:封装通用基类 ViewModelBase

实际项目不会每个 VM 都写一遍,通常抽成基类:

// 引入核心类(RelayCommand 所在)
using _00022.WPF_彻底搞懂_INotifyPropertyChanged.Core;
// 引入实体模型(User 类)
using _00022.WPF_彻底搞懂_INotifyPropertyChanged.Model;
using System;
// 可观察集合(列表自动刷新 UI)
using System.Collections.ObjectModel;
// WPF 命令接口
using System.Windows.Input;

// ViewModel 命名空间
namespace _00022.WPF_彻底搞懂_INotifyPropertyChanged.ViewModels
{
    /// <summary>
    /// 主页面 ViewModel
    /// 继承 ViewModelBase 拥有属性通知功能
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        // 输入框绑定的文本
        private string _inputText;
        // 选中的用户项
        private User _selectedUser;

        /// <summary>
        /// 输入框文本属性(UI 双向绑定)
        /// </summary>
        public string InputText
        {
            get => _inputText;
            set => SetProperty(ref _inputText, value);
        }

        /// <summary>
        /// 当前选中的用户(UI 绑定选中项)
        /// </summary>
        public User SelectedUser
        {
            get => _selectedUser;
            set => SetProperty(ref _selectedUser, value);
        }

        /// <summary>
        /// 用户列表(绑定到列表控件,自动刷新 UI)
        /// </summary>
        public ObservableCollection<User> Users { get; }

        /// <summary>
        /// 提交命令(按钮绑定)
        /// </summary>
        public ICommand SubmitCommand { get; }

        /// <summary>
        /// 构造函数:初始化数据 + 命令
        /// </summary>
        public MainViewModel()
        {
            // 初始化用户列表,给两条默认数据
            Users = new ObservableCollection<User>
            {
                new User { Id = 1, Name = "张三", Age = 20 },
                new User { Id = 2, Name = "李四", Age = 25 }
            };

            // 给命令赋值:点击按钮执行 UpdateRandomText
            SubmitCommand = new RelayCommand(UpdateRandomText);
        }

        /// <summary>
        /// 按钮点击执行:生成随机文本
        /// </summary>
        private void UpdateRandomText()
        {
            InputText = $"随机文本_{new Random().Next(1000, 9999)}_{_selectedUser?.Name}_{_selectedUser?.Age}";
        }

        /// <summary>
        /// 外部调用:直接更新输入框文本
        /// </summary>
        public void UpdateText(string text)
        {
            InputText = text;
        }
    }
}

使用:

public class MainViewModel : ViewModelBase
{
    /// <summary>
    /// 输入框文本属性(UI 双向绑定)
    /// </summary>
    public string InputText
    {
         get => _inputText;
         set => SetProperty(ref _inputText, value);
    }
}

非常简洁、规范、通用。


五、XAML 绑定示例

<Grid Margin="20">
     <StackPanel>
        <TextBox Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}"
                 FontSize="18" Margin="0 0 10 0"/>

        <ListBox ItemsSource="{Binding Users}"
                 SelectedItem="{Binding SelectedUser}"
                 Height="150" Margin="0 0 10 0">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Id}" Width="30"/>
                        <TextBlock Text="{Binding Name}" Width="100"/>
                        <TextBlock Text="{Binding Age}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <!-- 只保留 Command,去掉 Click -->
        <Button Content="随机更新文本" Command="{Binding SubmitCommand}" FontSize="16"/>
    </StackPanel>
</Grid>

后台绑定 DataContext:

// 持有 ViewModel 实例(供界面绑定使用)
public MainViewModel ViewModel { get; }

// 窗口构造函数
public MainWindow()
{
    // 初始化界面控件
    InitializeComponent();

    // 创建 ViewModel 实例
    ViewModel = new MainViewModel();
    // 关键:将 DataContext 设置为 ViewModel
    // 让界面能绑定到 ViewModel 里的属性和命令
    DataContext = ViewModel;
}

六、常见问题

  1. UI 不更新

    • 没继承 INotifyPropertyChanged
    • 没调用 OnPropertyChanged
    • 属性名写错
  2. 输入框改了,ViewModel 收不到
    TextBox 默认 LostFocus 才更新,加上:

    UpdateSourceTrigger=PropertyChanged
    
  3. 多线程更新 UI 报错
    用 Dispatcher 包裹:

    Application.Current.Dispatcher.Invoke(() =>
    {
        Name = "新名称";
    });
    

七、总结

  • INotifyPropertyChanged = WPF 数据绑定的心脏
  • 所有 MVVM ViewModel 都应继承实现它
  • 封装成 ViewModelBase 是行业标准写法
  • 属性变化 → 触发事件 → UI 自动更新

掌握它,你才算真正入门 WPF 数据绑定。


👋 关注我!持续分享 C# 实战技巧、代码示例 & 技术干货

  • 获取示例代码,轻松上手!
Wpf:通知更改的使用(INotifyPropertyChanged ) INotifyPropertyChanged 接口:用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知。继承ViewModelBase 类即可 在具体使用的时候调用onproperchanged函数。对于对多个值的更改 将调用的内容 封装到对应的函数 可以添加一个专门用于更改值的类中。如何让函数自动识别需要修改的值?完成对text文本的值更改。 阅读详情

相关推荐

WPF响应式UI的基础:INotifyPropertyChanged

摘要:本文详细介绍了WPF中INotifyPropertyChanged接口的实现与应用。主要内容包括:1)基础实现模板与标准属性实现方案;2)利用CallerMemberName特性优化属性变更通知;3)不同场景下的数据更新触发策略;4)高级应用技巧如表达式树优化、性能优化和跨平台实现;5)常见问题排查方法。通过具体代码示例,展示了如何构建高效可靠的数据绑定机制,涵盖线程安全、内存管理和通知频率控制等关键问题,为MVVM模式开发提供了完整的解决方案。

Hare的博客 1518

C#-INotifyPropertyChanged(解决数据绑定的界面刷新问题)

C#-INotifyPropertyChanged(解决数据绑定的界面刷新问题) 最近做项目用到DataGridView(property同理),用它绑定数据源后,如果数据源中的数据修改无法及时刷新到控件上,必须切换单元格的焦点才能导致刷新显示新数值,通过查官方文档,用INotifyPropertyChanged解决此问题。 案例如下: 首先定义一个类:Customer pu...

u014090257的博客 1万+

WPF之INotifyPropertyChanged实现

在WPF应用程序开发中,数据绑定是最核心的特性之一,它使视图层(UI)和数据层能够自动同步。而INotifyPropertyChanged接口则是实现这种同步机制的基础,它允许对象在属性值变化时通知UI进行更新。本文将深入探讨INotifyPropertyChanged接口的实现与应用,帮助开发者构建响应式的WPF应用程序。属性变化触发事件通知更新数据对象INotifyPropertyChangedPropertyChanged绑定系统UI元素 INotifyPropertyChanged接口基础 接口定义

冰茶的博客 1620

WPF中INotifyPropertyChanged用法

1.先建立类,在类中输入propfull,双击Tab按键 2.在头部引入 using System.ComponentModel; 3.建立BindingBase类,输入:后,选择继承INotifyPropertyChanged,再点击实现接口, 4.写入无返回值的虚方法 OnPropertyChanged 5.用建立的类,继承BindingBase,再调用OnPropertyChanged方法 注意:此处用了nameof,可以对于适用于任何类型。 ...

故里2130 3759

WPF入门第六篇 界面绑定属性刷新 INotifyPropertyChanged

前言 本文是wpf入门系列第五篇,面向有winform或者web前端基础的、并且也有C#基础的同学。 本文简单的介绍了 WPF 中界面绑定值得刷新问题, INotifyPropertyChanged 的作用及用法,以及对它的封装使用。其中,封装使用参考了WPF的开源框架ReactiveUI。 本文使用了 Visual Studio 2017 进行演示讲解。 wpf入门系列导航页面: https:...

wf824284257的博客 1万+

[WPF]INotifyPropertyChanged接口用法

先看看如下例子,不使用INotifyPropertyChanged接口的话会存在什么问题。 不使用INotifyPropertyChanged接口 新建一个项目,其中新建一个类叫做Person.cs,这个类里面有3个字段分别是姓名、年龄、爱好,然后将字段封装。代码如下 using System; using System.Collections.Generic; using System.Linq...

qq_20481125的博客 2995

【WPF开发高手进阶】:彻底搞懂INotifyPropertyChanged与双向绑定的完美协作

掌握WPF数据绑定双向绑定模式,轻松实现界面与数据的实时同步。本文深入解析INotifyPropertyChanged接口的应用场景与实现原理,揭示其在MVVM架构中的关键作用。通过典型代码示例展示属性变更通知机制,提升开发效率与维护性,值得收藏。

ProceSeed的博客 863

WPF中INotifyPropertyChanged接口的封装与实践

是一个在 .NET Framework 中定义的接口,位于命名空间中。当一个对象中的属性值发生变化时,实现了此接口的对象可以通知其属性值的任何订阅者。这是通过在属性值更改时引发事件来实现的。此模式被称为“发布-订阅”模式,是响应式编程的核心概念之一。在 WPF 应用开发中,此接口与数据绑定机制紧密集成,使得视图(View)能够自动响应数据模型(Model)的更改。当数据模型的属性发生变化时,视图会自动更新,无需手动编写代码来刷新界面。

weixin_35871529的博客 903

【WPF】聊聊WPF中INotifyPropertyChanged [TOC]

接口用于向客户端发出某一属性值已更改的通知。在应用有两种方式OneTime模式、OneWay模式和TwoWay模式。OneTime模式OneTime模式是一个初始化一次绑定。不常用。OneWay模式绑定源的每一次变化都会通知绑定目标,但是绑定目标的改变不会改变绑定源。当绑定源的数据实体类没有实现INotifyPropertyChanged接口时,当改变了数据源,发现绑定目录的UI上的相应的数据不会立即变化。TwoWay模式TwoWay。

记录总结工作过往 3043

深入理解WPF中MVVM模式下的ICommand与INotifyPropertyChanged实现

MVVM(Model-View-ViewModel)设计模式是一种流行的软件架构模式,被广泛用于WPF(Windows Presentation Foundation)和Silverlight应用程序中。它通过分离用户界面(View)的逻辑与业务逻辑(Model)来提高应用程序的可测试性、可维护性和可扩展性。在MVVM模式中,ViewModel充当Model和View之间的桥梁。它订阅Model中的变更通知,并将这些变更转换为View可以使用的形式,同时提供命令(ICommand)来处理用户的输入。

weixin_42499004的博客 1171

WPF INotifyPropertyChanged示例,数据绑定到控件,控件内容随变量的变化而变化

本INotifyPropertyChanged示例中,将一个类变量(Student)绑定到一个控件上,在代码中改变变量值,并立刻引起控件值的变化。此代码经过删减,仅仅保留精简内容,添加注释,简洁明了。 调试环境:Visual Studio 2017+C#4.61

WPF中 INotifyPropertyChanged

在Windows Presentation Foundation (WPF)中,INotifyPropertyChanged。是.NET框架提供的一个编译器特性(Compiler Feature)参数,将其设为调用方法的成员名称,即"MyProperty"。的值改变时,绑定系统能够准确地知道哪个属性发生了变化并作出相应的更新。在C#中,CallerMemberName。是一个核心接口,用于实现。实现中,我们可以使用。在此版本中,当你调用。时,编译器会自动填充。

以梦为马 不负韶华 1897

WPF入门第6篇 界面绑定属性刷新 INotifyPropertyChanged 的示例项目源码

WPF入门第6篇 界面绑定属性刷新 INotifyPropertyChanged 的示例项目源码。 具体可以查看博客 : https://blog.youkuaiyun.com/wf824284257/article/details/89083825

WPF INotifyPropertyChanged

简介: 获取或设置控件元素的数值,需要INotifyPropertyChanged接口。自定义一个实现了INotifyPropertyChanged接口的类。这个接口是为了发出属性更改的通知,即实现了这个接口将会实现当源对象的公共属性发生改变时,该属性的值会立即响应到界面上显式,或者获取界面的数据。 介绍: Source 指向源对象的引用,即提供数据的对象。一般都是指定的。 RelativeSource 使用RelativeSource对象指定绑定源的相对位置,默认...

路过 1612

WPF,实现INotifyPropertyChanged例子

这是一个实现INotifyPropertyChanged例子,根据str1, str2 的实时输入而改变按钮是否可用,如果str1的长度大于str2的长度,则按钮可用,否则按钮不可用

基于UWB技术的自动跟随避障系统设计研究

基于UWB技术的自动跟随避障系统设计研究 摘要:目前我国针对自动跟随避障系统方面的研究较少,同时国内自动跟随避障系统仍然处在未成熟阶段,多数仍停留在应用蓝牙控制或摄像头捕捉这类跟随方式,但这类方式在实际应用过程中往往会出现易受干扰,精度差,易受环境干扰等问题,这不仅会降低自动跟随避障系统的性能,同时也会对用户造成诸多困扰。因此,就需要结合目前较为有效的UWB技术,对自动跟随避障系统进行设计。基于此,本文首先将会针对UWB技术展开概述,而后对基于UWB技术的自动跟随避障系统组成展开分析,进而对基于UWB技术的

qq_43543515的博客 7991

WPF INotifyPropertyChanged使用方法

扣扣技术交流群:460189483 INotifyPropertyChanged 接口:向客户端发出某一属性值已更改的通知。 NotifyPropertyChanged接口用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知。 一般使用地方是:加载数据时,及时更新相应的数据加载名称。操作功能时,及时提示相应的错误信息。 实例: xaml代码: <TextBlo...

u014453443的博客 1605

【科研绘图】【数据拟合曲线】:附Origin详细画图流程

拟合曲线图

weixin_50236590的博客 4万+

WPF中核心接口 INotifyPropertyChanged​

它包含一个事件:​​​​:当某个 ​​绑定属性的值发生变化时​​,类需要触发这个事件,并传入发生变化的属性名(通常是WPF 的绑定系统(如)会 ​​监听这个事件​​,一旦属性值变了,就会 ​​自动更新 UI​​。项目说明​​INotifyPropertyChanged 是什么?​​一个接口,用于在属性值更改时通知绑定系统(WPF 数据绑定的核心)​​类级别实现(推荐)​​。

zzwwgg1984的博客 1081

Unity 数字孪生实战:PiXYZ Plugin工业模型高效处理指南

本文是Unity数字孪生实战指南,重点介绍了如何使用PiXYZ Plugin高效处理工业CAD模型。针对工业模型导入Unity时面临的格式壁垒、数据爆炸和资产混乱等核心痛点,文章提供了从环境安装、基础导入到智能减面、资产清理的完整解决方案,并分享了预设自动化、运行时导入等高级技巧与性能优化策略,帮助开发者快速打通工业设计与实时交互流程。

weixin_29009501的博客 255

Python+Selenium实现抖音博主批量监控:300+账号实时更新通知(附完整代码)

本文详细介绍了如何使用Python和Selenium构建一个高可用的抖音博主批量监控系统。通过架构设计、Cookie管理、高效轮询与差异检测等核心模块,实现300+账号的实时更新追踪与通知。文章提供了完整的代码实现,并重点探讨了性能优化、异常处理及服务器部署等实战经验,帮助开发者打造稳定、可控的自动化监控解决方案。

weixin_29274969的博客 192

WPF MVVM INotifyPropertyChanged

本文介绍wpf MVVM(Model-View- ViewModel ) 模式,以及界面 绑定属性,INotifyPropertyChanged的刷新功能 ,附加知识点类的继承,UserControl的使用。 使用开发工具 vs2019 1.创建wpf项目 2.项目名称 MvvmDemo 3.创建UserControl 在PersonUserControl中加入控件...

u010549750的专栏 692

[SoC]SoC验证中bootcode与firmware相关验证经验总结

本文总结了SoC验证中bootcode和firmware的验证经验。重点介绍了两种数据加载方法:1)使用Verilog系统函数$readmemh/$readmemb直接写入ROM/ARAM,需注意文件路径、格式和斜杠方向;2)通过Memory Hierarchy在initial块中操作,需要添加适当延时并注意路径拼接。文章还提供了在testcase phase中先读取数据到HASH再写入SRAM的示例,并强调加载后需使能edc_bypass以避免ECC错误。验证过程中需特别注意文件位置、格式要求及路径处理等

元直的博客 2497
上一篇: 深入浅出腾讯云COS对象存储:从概念到实战,全方位解析海量非结构化数据管理方案
下一篇: 从 MVVMLight 到 CommunityToolkit.Mvvm:MVVM 框架的现代化演进与全面对比
bugcome_com
博客等级 码龄3年 32粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值