[转载]PropertyChanged 事件

2023-11-12

在.NET平台上,数据绑定是一项令人十分愉快的技术。利用数据绑定能减少代码,简化控制逻辑。

通常,可以将某个对象的一个属性绑定到一个可视化的控件上,当属性值改变时,控件上的显示数据也随之发生变化。要实现这一功能,只需要为自定义对象实现 INotifyPropertyChanged 接口即可。此接口中定义了 PropertyChanged 事件,我们只需在属性值改变时触发该事件即可。下面的例子说明如何绑定如何自定义可用于数据绑定的对象:

假设我们有自定义对象 CustomizedObject 和窗体上的 Label 控件 label1,想要将 CustomizedObject 的 Date 属性和 label1.Text 关联起来,Date 属性值会在程序运行过程当中发生变化(例如点击 Button 控件 button1),并且直接反映在 label1.Text 上。下面的代码可以实现上述功能:
这个例子是点击 按钮后 日期自动加1.

using System;

using System.ComponentModel;

using System.Windows.Forms;

 

namespace WindowsFormsApplication1

{

    public partial class Form1 : Form

    {

        private CustomizedObject myObject;
 

        public Form1()

        {

            InitializeComponent();

 

            // 初始化CustomizedObject对象

            myObject = new CustomizedObject { Date = DateTime.Now };

 

            // 绑定对象的属性到label1

            label1.DataBindings.Add("Text", myObject, "Date");

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            // 点击按钮改变对象的属性值

            myObject.Date = myObject.Date.AddDays(1);

        }

 

    }

 

    // 自定义对象 CustomizedObject 并实现 INotifyPropertyChanged 接口

    public class CustomizedObject : INotifyPropertyChanged

    {

        private DateTime dateValue;
 

        // 自定义一个 Date 属性

        public DateTime Date

        {

            get { return dateValue; }

            set

            {

                dateValue = value;

                NotifyPropertyChanged("Date");

            }

        }

 

        #region INotifyPropertyChanged Members

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        // 添加一个触发 PropertyChanged 事件的通用方法

        protected virtual void NotifyPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

         #endregion

    }

}

其实从上面的例子中可以学习到如何自定义事件,这在开发控件时十分有用且非常重要。通过观察 INotifyPropertyChanged 接口可以知道它内部有一个成员,那就是:

event PropertyChangedEventHandler PropertyChanged;

而其中的 PropertyChangedEventHandler 实质上是一个委托,明白了这一点就可以自定义事件了。

现在,开始为 Form1 自定义事件 DateChanged (事件一般是定义在控件或组件中的,这里只是为了说明其过程而没有重新定义一个控件),首先需要一个事件参数类型:

public class DateChangedEventArgs : EventArgs

{

    public DateTime OldValue { get; set; }

    public DateTime NewValue { get; set; }

}

声明一个事件处理委托

public delegate void DateChangedHandler(object sender,
DateChangedEventArgs e);

我们可以将事件直接添加到Form1的定义中,但有时为了代码的通用性,可以将事件封装到一个接口中,例如:

public interface IDateChanged

{

    event DateChangedHandler DateChanged;

}

然后我们为Form1实现 IDateChanged 接口,并在button1点击时触发该事件。以下是完整代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 事件处理propettychanged
{
    public partial class Form1 : Form, IDateChanged
    {
        private CustomizedObject myObject;
        public Form1()
        {
            InitializeComponent();
            // 初始化CustomizedObject对象
            myObject = new CustomizedObject { Date = DateTime.Now };
            // 绑定对象的属性到label1
            label1.DataBindings.Add("Text", myObject, "Date");
            // 添加 DateChanged 事件的处理逻辑
            this.DateChanged += new DateChangedHandler(Form1_DateChanged);
        }
        private void Form1_DateChanged(object sender, DateChangedEventArgs e)
        {
            string message = string.Format(
                "DateChanged event triggered!nOldValue: {0}nNew Value: {1}",
                e.OldValue,
                e.NewValue);
            MessageBox.Show(message);
        }



        private void button1_Click(object sender, EventArgs e)

        {
            // 点击按钮改变对象的属性值并触发 DateChanged 事件
            DateChangedEventArgs ev = new DateChangedEventArgs
            {
                OldValue = myObject.Date,
                NewValue = myObject.Date.AddDays(1)
            };
            myObject.Date = ev.NewValue;
            DateChangedMethod(ev);
        }


        public event DateChangedHandler DateChanged;

        // 添加一个触发 DateChanged 事件的通用方法

        protected virtual void DateChangedMethod(DateChangedEventArgs e)
        {
            if (DateChanged != null)
            {
                DateChanged(this, e);
            }
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }
    }



    // 自定义对象 CustomizedObject 并实现 INotifyPropertyChanged 和 IDateChanged 接口

    public class CustomizedObject : INotifyPropertyChanged
    {
        private DateTime dateValue;
        // 自定义一个 Date 属性
        public DateTime Date
        {
            get { return dateValue; }
            set
            {
                dateValue = value;
                NotifyPropertyChanged("Date");
            }
        }
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        // 添加一个触发 PropertyChanged 事件的通用方法
        protected virtual void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }



    // DateChanged 事件委托

    public delegate void DateChangedHandler(object sender, DateChangedEventArgs e);



    // 用于封装事件的接口

    public interface IDateChanged
    {
        event DateChangedHandler DateChanged;
    }



    // DateChanged 事件参数

    public class DateChangedEventArgs : EventArgs
    {
        public DateTime OldValue { get; set; }
        public DateTime NewValue { get; set; }
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[转载]PropertyChanged 事件 的相关文章

  • C#中的委托(Delegate)和事件 (Event)详解与使用范例

    一 委托 Delegate 1 委托 Delegate 简介 最近天气晴雨不定 你因为害怕打游戏时忘记在下雨时收衣服或者在天晴时把衣服挂出去 于是你委托好友小明在天气发生变化时打电话通知你 这就是一种委托 下面是这种委托的实例代码 定义一个
  • .net event 使用 Action

    Action lt string gt methodCall 61 x 61 gt x 43 61 34 haha 34 MessageBox Show x public event Action lt string gt BoilerEv
  • C# Event Action与Invoke

    趁着1024这个好日子来讲一下 通常在C 中 为了将功能模块化 我们会把重复使用的功能写到类 Class 里面 但是写在类里面的方法是无法直接对主窗体界面进行操作的 这个时候我们就需要使用 委托 关于委托的讲解可以参考这篇 https ww
  • 你是如何理解var e=e||window.event的------Day26

    你是如何理解var e 61 e window event的 xff1f 相信很多人都能给我个回答说是 xff1a 为了实现多种浏览器兼容 不错 xff0c 确实是为了实现浏览器兼容 xff0c 但是它又是如何实现浏览器兼容的呢 xff1f
  • gen_fsm中send_event和send_all_state_event的区别

    文档原文 xff1a The difference between send event and send all state event is which callback function is used to handle the e
  • C# 中delegate、event、Action、Func详解

    都属于委托 xff0c 只是展现的形式不同而已 xff0c 无论哪种 xff0c 其实都可以采用delegate实现 xff0c 为什么会出现另外的三种呢 xff1f 因为delegate是很宽泛的 xff0c 格式内容都不受限 xff0c
  • esp32 event loop handle 代码

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • C++编程——继承

    文章目录 1 继承的基本语法 2 继承方式 3 继承的对象模型 4 继承中构造和析构顺序 5 继承中同名成员处理 6 继承中同名静态成员处理方式 6 1 通过对象访问 6 2 通过类名访问 7 多继承语法 7 1 多继承的对象模型 8 菱形
  • angular4中ngModel双向绑定在限制输入情况下与value值不一致的问题及尝试的解决方法

    近期公司的一个后台项目在使用angular4进行开发 随着项目的推进和迭代开发 需要对有的input框的value值进行限制输入 例如目前项目的一些input框只允许输入数字和 这两种形式的内容 就在input标签的中添加了 keyup 属
  • linux通信机制signal()函数详解

    我们来谈一谈signal 函数的作用 linux系统提供了signal 和sigaction 两个函数来改变对于信号的处理方法 其中signal 是一个基于sigaction 系统调用的glibc库函数 其行为在不同的linux操作系统存在
  • js中事件对象event

    一 Event对象 Event 对象代表事件的状态 比如事件在其中发生的元素 键盘按键的状态 鼠标的位置 鼠标按钮的状态 事件通常与函数结合使用 函数不会在事件发生前被执行 当一个事件发生的时候 和当前这个对象发生的这个事件有关的一些详细信
  • 位运算符(一):C/C++位运算符

    位运算是指按二进制进行的运算 在程序中 常常需要处理二进制位的问题 C C 语言提供了6个位操作运算符 这些运算符只能用于整型操作数 即只能用于带符号或无符号的char short int与long类型 在实际应用中 建议用unsigned
  • 定义和声明的区别

    对于变量来说 定义就是声明 例如 int a 我们可是说它是定义也可以说它是声明 但是对于函数来说定义和声明完全不是一回事 void sum int a int b 这是函数的声明 void sum int a int b 整体是函数的定义
  • KEIL编译出现错误“source file is not valid utf-8”

    KEIL编译出现错误 source file is not valid utf 8 在外面复制了一段代码 c文件一直报错source file is not valid utf 8的错误 经查找原因就是 文件中出现中文符号导致的 特别是中文
  • IoT reigns supreme at upcoming Embedded Linux Conference

    本文转载至 http linuxgizmos com linux foundation details embedded linux conference agenda 转载说明 今年的嵌入式 Linux 大会内容非常丰富 包括 Linus
  • 记一次线性插值方法(Mathf.Lerp())的使用体会

    对Mathf Lerp 方法使用体会源于一次开发游戏对警报灯闪烁问题进行处理时 public static float Lerp float from float to float t 分析一下对线性插值函数的认识 就是在from与to之间
  • C# 理解Thread.Sleep()方法 (转载学习)

    我们可能经常会用到 Thread Sleep 函数来使线程挂起一段时间 那么你有没有正确的理解这个函数的用法呢 思考下面这两个问题 1 假设现在是 2008 4 7 12 00 00 000 如果我调用一下 Thread Sleep 100
  • c语言之字符串数组

    还是在写图的存储结构的时候 遇到了问题 就是如何在一个数组中存放字符串 我相信这个问题 对于面向对象的编程语言来说 轻而易举 比如对于Java来说 直接像下面就可以了 但是c语言没有String这个类型 能想到存放字符串的数据类型就是cha
  • c#中日志NLog配置问题

    Failed obtaining configuration for Common Logging from configuration section common logging 在配置中没有配置对 另外很有可能是NLog 的配置文件没
  • Embedded world conference 2015

    本文转载至 http www embedded world eu program html 一些相关的议程 Tuesday February 24 13 30 14 30 Keynote 1 Conference Keynote 09 30

随机推荐

  • 字符串哈希

    字符串哈希 我们可以把一个字符串哈希处理成一个数字 具体做法 将字符串看作是一个p进制数 p大于字符的ascii码值 acbd哈希成数字是 a p 3 c p 2 b p 1 d p 0 modQ p一般取131或者13331 Q取2e64
  • Docker学习笔记

    五 Docker 1 简介 Docker是一个开源的应用容器引擎 是一个轻量级容器技术 Docker支持将软件编译成一个镜像 然后在镜像中各种软件做好配置 将镜像发布出去 其他使用者可以直接使用这个镜像 运行中的这个镜像称为容器 容器启动是
  • 微信小程序静态初步

    社团微信小程序 1 由于兴趣驱动 一直在学习微信小程序 由于之前一直学习Java 但是大三第一学期即将结尾 所以为了能让下学期的学习减少工作量所以就打算利用闲散时间开发小程序 于是就拿社团为例子 自己一步步摸索 现在只是初步学习 所以这些天
  • mysql-Innodb事务隔离级别-repeatable read详解(转)

    mysql Innodb事务隔离级别 repeatable read详解 转 一 事务隔离级别 ANSI ISO SQL标准定义了4中事务隔离级别 未提交读 read uncommitted 提交读 read committed 重复读 r
  • vim配置经典

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在终端 输入以下命令来编辑vimrc配置文件 sudo vim etc vim vimrc 或者 sudo gedit etc vim vimrc 将其复制粘贴进去 Des
  • GeoDa:入门基础

    前言 GeoDa是一个免费的开源软件工具 用于空间数据分析 它旨在通过探索和建模空间模式来促进数据分析的新见解 GeoDa是由Luc Anselin博士和他的团队开发的 该项目为探索性空间数据分析 ESDA 方法提供了用户友好的图形界面 例
  • mysql中join源码分析,MySQL中Join算法实现原理分析[图]

    在MySQL 中 只有一种 Join 算法 就是大名鼎鼎的 Nested Loop Join 他没有其他很多数据库所提供的 Hash Join 也没有 Sort Merge Join 顾名思义 Nested Loop Join 实际上就是通
  • 把二叉树转换成树(代码实现)

    前言 相信大家都知道二叉树如何转化成树 但是让你用代码实现 却发现自己无从下手 下面我将用代码实现 思想 树用二叉树来存储的话 那么类型是 左儿子 右兄弟 即二叉树某节点和它的左儿子在树中的关系也是父子关系 而与右儿子在树中的关系是兄弟关系
  • 机器视觉中非常好的github仓库

    AwesomeComputerVision Multi Object Tracking Paper List https github com SpyderXu multi object tracking paper list awesom
  • Oracle VM VirtualBox 不显示64位系统 linux 64 redhat 64

    打开BIOS里的虚拟化技术 修改bios中的virtualization 设为ENABLED
  • Elasticsearch 基本使用(三)条件查询

    条件查询 简单查询 term terms range match debug 查看分词结果 match phrase match phrase prefix match bool prefix multi match 复合查询 bool 查
  • 【c++之于c的优化 - 下】

    前言 一 inline 概念 以inline修饰的函数叫做内联函数 编译时C 编译器会在调用内联函数的地方展开 没有函数调用建立栈帧的开销 内联函数提升程序运行的效率 如果在上述函数前增加inline关键字将其改成内联函数 在编译期间编译器
  • 获取outputstream大小_关于inputStream.available()方法获取下载文件的总大小

    如果用inputStream对象的available 方法获取流中可读取的数据大小 通常我们调用这个函数是在下载文件或者对文件进行其他处理时获取文件的总大小 以前在我们初学File和inputStream和outputStream时 有需要
  • C++标准库之中文输出详细介绍【转】

    iostream printf wprintf和中文输出 本文引用出处 http www enjoysoft cn blog post 62 html使用C 标准库的iostream 可以方便地将控制台 文件 字符串以及其它可扩充的外部表示
  • Vue使用v-for遍历map

    功能 遍历数据库中按钮的图片和名字 当页面打开时 触发查询事件 以下图形式显示出来 前端代码 遍历存在数据库中的按钮名称和图片名称 其中按钮的click事件名称和按钮图片名称相同
  • Linux命令 理解

    RPM常用命令参数列表 1 安装一个包 rpm ivh 2 升级一个包 rpm Uvh 注意U一定要大写 i 安装 U 升线安装 h 以 显示安装进度 v 显示附加信息 3 移走一个包 rpm e 4 安装参数 force 即使覆盖属于其它
  • 变透明的黑匣子:UCLA 开发可解释神经网络 SNN 预测山体滑坡

    内容一览 由于涉及到多种时空变化因素 山体滑坡预测一直以来都非常困难 深度神经网络 DNN 可以提高预测准确性 但其本身并不具备可解释性 本文中 UCLA 研究人员引入了 SNN SNN 具有完全可解释性 高准确性 高泛化能力和低模型复杂度
  • 基本的信号——矩阵脉冲信号(门函数)

    门函数的数学表达式为 example1 矩形脉冲信号的matlab代码如下 矩形脉冲信号 clc clear close all t 0 0 001 4 T 1 ft rectpuls t 2 T 2 T plot t ft 运行结果如下
  • Normalize 和 normalized

    首先说明下 normalized的是vector的属性 而Normalize 是vector的方法 normalized和Normalize 都是可读的 读到的值是单位向量的值 只是nomalized不会更改当前vector本身的值 只是返
  • [转载]PropertyChanged 事件

    在 NET平台上 数据绑定是一项令人十分愉快的技术 利用数据绑定能减少代码 简化控制逻辑 通常 可以将某个对象的一个属性绑定到一个可视化的控件上 当属性值改变时 控件上的显示数据也随之发生变化 要实现这一功能 只需要为自定义对象实现 INo