【WPF】 数据绑定机制之INotifyPropertyChanged

INotifyPropertyChanged 是 WPF 中的一个接口,用于实现 数据绑定 中的 属性更改通知。它的主要作用是,当对象的某个属性值发生更改时,通知绑定到该属性的 UI 控件更新其显示内容。

以下是有关 INotifyPropertyChanged 的详细信息和实现方法:


1. INotifyPropertyChanged 简介

INotifyPropertyChanged 定义在 System.ComponentModel 命名空间中,它只包含一个事件:

public interface INotifyPropertyChanged
{event PropertyChangedEventHandler PropertyChanged;
}
核心机制
  • PropertyChanged 是事件,当对象的属性发生更改时,触发此事件。
  • WPF 数据绑定引擎会监听这个事件,并根据通知更新 UI。

2. 使用场景

在 MVVM 模式中,INotifyPropertyChanged 通常用于 ViewModel 层,确保当属性值更改时,UI 会自动更新。


3. 实现步骤

Step 1: 实现接口
using System.ComponentModel;public class Person : INotifyPropertyChanged
{// 实现 INotifyPropertyChanged 接口public event PropertyChangedEventHandler PropertyChanged;// 用于触发 PropertyChanged 事件的方法protected void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}private string name;public string Name{get => name;set{if (name != value){name = value;// 通知绑定 Name 的 UI 更新OnPropertyChanged(nameof(Name));}}}
}
Step 2: 在 XAML 中绑定

创建一个简单的 WPF 界面,绑定到 PersonName 属性。

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="INotifyPropertyChanged Example" Height="200" Width="300"><StackPanel><TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Margin="10"/><TextBlock Text="{Binding Name}" Margin="10"/></StackPanel>
</Window>
Step 3: 设置 DataContext

MainWindow.xaml.cs 中,将 DataContext 设置为 Person 对象。

using System.Windows;namespace WpfApp
{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();// 创建 Person 对象并绑定到窗口DataContext = new Person { Name = "John Doe" };}}
}

4. 运行效果

  1. TextBox 中修改 Name 的值时,TextBlock 会自动更新为新的值。
  2. 数据绑定引擎通过 INotifyPropertyChanged 的通知机制感知到属性的更改,并更新绑定的 UI。

5. 注意事项

  1. 避免直接使用字符串: 使用 nameof 操作符替代硬编码的字符串,避免因属性名变更导致的问题。

    OnPropertyChanged(nameof(Name));
    
  2. 批量更新: 如果多个属性发生更改,可以调用 OnPropertyChanged(null)OnPropertyChanged(string.Empty),通知所有属性值发生变化。

  3. 多属性通知: 如果一个属性的更改会影响其他属性,可以触发多个 OnPropertyChanged 调用。

    OnPropertyChanged(nameof(Name));
    OnPropertyChanged(nameof(FullName));
    

6. 使用封装提高代码复用性

可以将 INotifyPropertyChanged 的逻辑封装到基类中,减少重复代码:

public class ObservableObject : INotifyPropertyChanged
{public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}protected bool SetProperty<T>(ref T field, T value, string propertyName){if (!Equals(field, value)){field = value;OnPropertyChanged(propertyName);return true;}return false;}
}

子类实现

public class Person : ObservableObject
{private string name;public string Name{get => name;set => SetProperty(ref name, value, nameof(Name));}
}

7. WPF MVVM Toolkit 实现的 INotifyPropertyChanged

WPF MVVM Toolkit(Microsoft.Toolkit.Mvvm)是 Microsoft 推出的 MVVM 框架,它在 INotifyPropertyChanged 的基础上进行了封装和简化。以下是它的特点和实现:

主要特点
  1. 提供了 ObservableObject 基类,简化了 INotifyPropertyChanged 的实现。
  2. 提供了 SetProperty 方法,避免手动触发 PropertyChanged
  3. 支持属性变更通知的自动化和高效实现。
using CommunityToolkit.Mvvm.ComponentModel;public class Person : ObservableObject
{private string name;public string Name{get => name;set => SetProperty(ref name, value);}
}

在实现 INotifyPropertyChanged 接口时,OnPropertyChanged 方法是开发者定义的用于触发属性变更通知的辅助方法。当某个属性的值发生变化时,通常由属性的 set 访问器调用 OnPropertyChanged 方法,从而触发 PropertyChanged 事件。


触发过程

  1. 属性的 set 访问器检测到值发生了变化。
  2. 调用 OnPropertyChanged 方法。
  3. OnPropertyChanged 方法触发 PropertyChanged 事件。
  4. WPF 或其他数据绑定框架监听到 PropertyChanged 事件后,更新绑定到该属性的 UI。
  5. Event PropertyChangedEventHandler 用函数包裹起来触发
  6. 实际中用框架,比如Microsoft.Toolkit.Mvvm, 提供了 ObservableObject 基类,简化了 INotifyPropertyChanged 的实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/892111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netron可视化深度学习的模型框架,大大降低了大模型的学习门槛

深度学习是机器学习的一个子领域&#xff0c;灵感来源于人脑的神经网络。深度学习通过多层神经网络自动提取数据中的高级特征&#xff0c;能够处理复杂和大量的数据&#xff0c;尤其在图像、语音、自然语言处理等任务中表现出色。常见的深度学习模型&#xff1a; 卷积神经网络…

Robot---奇思妙想轮足机器人

1 背景 传统机器人有足式、轮式、履带式三种移动方式&#xff0c;每种移动方式都有各自的优缺点。轮式机器人依靠车轮在地面上移动&#xff0c;能源利用率高、移动速度快&#xff0c;但是仅以轮子与地面接触&#xff0c;缺乏越障能力和对复杂地形的适应能力&#xff0c;尤其面对…

用JAVA编写一个简单的小游戏

用Java语言编写一个简单的小游戏。这里是一个非常基础的猜数字小游戏的代码示例。在这个游戏中&#xff0c;程序会随机选择一个1到100之间的整数&#xff0c;玩家需要猜测这个数字是什么。每次猜测后&#xff0c;程序会告诉玩家他们猜的数字是太高了、太低了还是正确。 impor…

加速科技荣获“浙江省企业研究院”认定

近日&#xff0c;浙江省经济和信息化厅公布“2024年认定&#xff08;备案&#xff09;省级企业研发机构名单”。经过多轮严格评审和公示&#xff0c;加速科技荣获“省企业研究院”认定。这是加速科技继获国家级专精特新“小巨人”企业认定荣誉后的又一里程碑。 “浙江省企业研究…

MySQL使用navicat新增触发器

找到要新增触发器的表&#xff0c;然后点击设计&#xff0c;找到触发器标签。 根据实际需要&#xff0c;填写相关内容&#xff0c;操作完毕&#xff0c;点击保存按钮。 在右侧的预览界面&#xff0c;可以看到新生成的触发器脚本

性能测试05|JMeter:分布式、报告、并发数计算、性能监控

目录 一、JMeter分布式 1、应用场景 2、原理 3、分布式相关注意事项 4、分布式配置与运行 二、JMeter报告 1、聚合报告 2、HTML报告 三、并发用户数&#xff08;线程数&#xff09;计算 四、JMeter下载第三方插件 五、性能监控 1、Concurrency Thread Group 线程组…

(已开源-AAAI25) RCTrans:雷达相机融合3D目标检测模型

在雷达相机融合三维目标检测中&#xff0c;雷达点云稀疏、噪声较大&#xff0c;在相机雷达融合过程中提出了很多挑战。为了解决这个问题&#xff0c;我们引入了一种新的基于query的检测方法 Radar-Camera Transformer (RCTrans)。具体来说&#xff1a; 首先设计了一个雷达稠密…

Python----Python爬虫(利用bs4、pyquery、xpath爬取电影名和评分)

电影网址电影大全_好看的电影_最新好看的电影_电影排行榜-影视快搜 一、bs4 import requests from fake_useragent import UserAgent from bs4 import BeautifulSoup # 设置URL地址 urlhttp://kan.znds.com/movie/ # 设置请求头 headers{User-Agent:UserAgent().edge} # 发送…

Hbuilder ios 离线打包sdk版本4.36,HbuilderX 4.36生成打包资源 问题记录

1、打包文档地址https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios.html#%E9%85%8D%E7%BD%AE%E5%BA%94%E7%94%A8%E7%89%88%E6%9C%AC%E5%8F%B7 2、配置应用图标 如果没有appicon文件&#xff0c;此时找到 Assets.xcassets 或者 Images.xcassets(看你sdk引入的启动文件中…

TCP通信原理学习

TCP三次握手和四次挥手以及为什么_哔哩哔哩_bilibili

unity学习13:gameobject的组件component以及tag, layer 归类

目录 1 gameobject component 是unity的基础 1.1 类比 1.2 为什么要这么设计&#xff1f; 2 从空物体开始 2.1 创建2个物体 2.2 给 empty gameobject添加组件 3 各种组件和新建组件 3.1 点击 add component可以添加各种组件 3.2 新建组件 3.3 组件的操作 3.4 特别的…

MYSQL--------什么是存储过程和函数

什么是存储过程和函数 存储过程&#xff1a; 存储过程是一组预编译的 SQL 语句集合&#xff0c;存储在数据库服务器中&#xff0c;可通过名称调用执行。它可以包含数据操作语言&#xff08;DML&#xff09;、数据定义语言&#xff08;DDL&#xff09;、控制流语句等。存储过程主…

计算机网络 (30)多协议标签交换MPLS

前言 多协议标签交换&#xff08;Multi-Protocol Label Switching&#xff0c;MPLS&#xff09;是一种在开放的通信网上利用标签引导数据高速、高效传输的新技术。 一、基本概念 MPLS是一种第三代网络架构技术&#xff0c;旨在提供高速、可靠的IP骨干网络交换。它通过将IP地址映…

探索Facebook的区块链计划:未来社交网络的变革

随着区块链技术的迅速发展&#xff0c;社交网络领域正面临一场深刻的变革。Facebook&#xff0c;作为全球最大且最具影响力的社交平台之一&#xff0c;正在积极探索区块链技术的应用。本文将深入探讨Facebook的区块链计划&#xff0c;分析其潜在的变革性影响&#xff0c;并展望…

十年后LabVIEW编程知识是否会过时?

在考虑LabVIEW编程知识在未来十年内的有效性时&#xff0c;我们可以从几个角度进行分析&#xff1a; ​ 1. 技术发展与软件更新 随着技术的快速发展&#xff0c;许多编程工具和平台不断更新和改进&#xff0c;LabVIEW也不例外。十年后&#xff0c;可能会有新的编程语言或平台…

C# async和await

第一种&#xff1a; 多个异步任务按照顺序执行先让一个异步任务start 然后通过ContinueWith方法 在参数函数的表达式里面开启第二个任务如果要有第三个任务 需要在第二个任务ContinueWith方法中开启第三个任务 以此类推 可以实现多个异步任务顺序执行 上面这种方式绘出现地狱回…

Excel 技巧03 - 如何对齐小数位数? (★)如何去掉小数点?如何不四舍五入去掉小数点?

这几个有点儿关联&#xff0c;我都给放到一起了&#xff0c;不影响大家分别使用。 目录 1&#xff0c;如何对齐小数位数&#xff1f; 2&#xff0c;如何去掉小数点&#xff1f; 3&#xff0c;如何不四舍五入去掉小数点&#xff1f; 1&#xff0c;如何对齐小数位数&#xff…

node.js|浏览器插件|Open-Multiple-URLs的部署和使用,实现一键打开多个URL的强大工具

前言&#xff1a; 在整理各类资源的时候&#xff0c;可能会面临资源非常多的情况&#xff0c;这个时候我们就需要一款能够一键打开多个URL的浏览器插件了 说简单点&#xff0c;其实&#xff0c;迅雷就是这样的&#xff0c;但是迅雷是基于内置nginx浏览器实现的&#xff0c;并…

“AI 视频图像识别系统,开启智能新视界

咱老百姓现在的生活啊&#xff0c;那是越来越离不开高科技了&#xff0c;就说这 AI 视频图像识别系统&#xff0c;听起来挺高大上&#xff0c;实际上已经悄无声息地融入到咱们日常的方方面面&#xff0c;给咱带来了超多便利。 先讲讲安防领域吧&#xff0c;这可是 AI 图像识别的…

C语言 游动的小球

代码如下&#xff1a; 在这里插入代码片#include<stdio.h> #include<stdlib.h> #include<windows.h>int main() {int i,j;int x 5;int y 10;int height 20;int velocity_x 1;int velocity_y 1;int left 0;int right 20;int top 0;int bottom 10;while(1){…