【WinForm.NET开发】设计具有更改通知的出色数据源

本文内容

  1. 简单绑定的更改通知
  2. 基于列表的绑定的更改通知
  3. 自定义控件的更改通知
  4. 应用 PropertyNameChanged 模式
  5. 实现 INotifyPropertyChanged 接口
  6. 同步绑定

Windows 窗体数据绑定最重要的概念之一是更改通知。 为确保数据源和绑定控件始终具有最新数据,必须为数据绑定添加更改通知。 具体来说,你希望确保绑定控件在对其数据源进行更改时得到通知。 数据源在对控件的绑定属性进行更改时得到通知。

根据数据绑定的类型,有不同类型的更改通知:

  • 简单绑定,其中单个控件属性绑定到对象的单个实例。

  • 基于列表的绑定,它可以包括绑定到列表中项属性的单个控件属性或绑定到对象列表的控件属性。

此外,如果正在创建要用于数据绑定的 Windows 窗体控件,必须将 PropertyNameChanged 模式应用于控件。 将模式应用于控件后,会将对控件的绑定属性的更改传播到数据源。

1、简单绑定的更改通知

对于简单绑定,业务对象必须在绑定属性的值更改时提供更改通知。 可以通过为业务对象的每个属性公开一个 PropertyNameChanged 事件来提供更改通知。 同时需要使用 BindingSource 或首选方法将业务对象绑定到控件,在该方法中业务对象实现 INotifyPropertyChanged 接口并在属性值更改时引发 PropertyChanged 事件。 使用实现 INotifyPropertyChanged 接口的对象时,不必使用 BindingSource 将对象绑定到控件。 但建议使用 BindingSource

2、基于列表的绑定的更改通知

Windows 窗体依靠绑定列表来向绑定控件提供提供属性更改和列表更改信息。 属性更改是更改列表项属性值,列表更改是从列表中删除项或向列表添加项。 因此,用于数据绑定的列表必须实现 IBindingList,它提供两种类型的更改通知。 BindingList<T> 是 IBindingList 的通用实现,旨在与 Windows 窗体数据绑定一起使用。 可以创建一个 BindingList,其中包含实现 INotifyPropertyChanged 的​​业务对象类型,并且该列表将自动将 PropertyChanged 事件转换为 ListChanged 事件。 如果绑定列表不是 IBindingList,必须使用 BindingSource 组件将对象列表绑定到 Windows 窗体控件。 BindingSource 组件将提供属性到列表的转换,该转换类似于 BindingList 的属性到列表的转换。 

3、自定义控件的更改通知

最后,在控件端,必须为每个旨在绑定到数据的属性公开一个 PropertyNameChanged 事件。 然后将对控件属性的更改传播到绑定的数据源。 

4、应用 PropertyNameChanged 模式

下面的代码示例演示如何将 PropertyNameChanged 模式应用于自定义控件。 在实现与 Windows 窗体数据绑定引擎一起使用的自定义控件时,请应用该模式。

// This class implements a simple user control
// that demonstrates how to apply the propertyNameChanged pattern.
[ComplexBindingProperties("DataSource", "DataMember")]
public class CustomerControl : UserControl
{private DataGridView dataGridView1;private Label label1;private DateTime lastUpdate = DateTime.Now;public EventHandler DataSourceChanged;public object DataSource{get{return this.dataGridView1.DataSource;}set{if (DataSource != value){this.dataGridView1.DataSource = value;OnDataSourceChanged();}}}public string DataMember{get { return this.dataGridView1.DataMember; }set { this.dataGridView1.DataMember = value; }}private void OnDataSourceChanged(){if (DataSourceChanged != null){DataSourceChanged(this, new EventArgs());}}public CustomerControl(){this.dataGridView1 = new System.Windows.Forms.DataGridView();this.label1 = new System.Windows.Forms.Label();this.dataGridView1.ColumnHeadersHeightSizeMode =System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;this.dataGridView1.ImeMode = System.Windows.Forms.ImeMode.Disable;this.dataGridView1.Location = new System.Drawing.Point(100, 100);this.dataGridView1.Size = new System.Drawing.Size(500,500);this.dataGridView1.TabIndex = 1;this.label1.AutoSize = true;this.label1.Location = new System.Drawing.Point(50, 50);this.label1.Name = "label1";this.label1.Size = new System.Drawing.Size(76, 13);this.label1.TabIndex = 2;this.label1.Text = "Customer List:";this.Controls.Add(this.label1);this.Controls.Add(this.dataGridView1);this.Size = new System.Drawing.Size(450, 250);}
}

5、实现 INotifyPropertyChanged 接口

下面的代码示例演示如何实现 INotifyPropertyChanged 接口。 在 Windows 窗体数据绑定中使用的业务对象上实现该接口。 实现时,该接口将业务对象上的属性更改与绑定控件进行通信。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;// Change the namespace to the project name.
namespace binding_control_example
{// This form demonstrates using a BindingSource to bind// a list to a DataGridView control. The list does not// raise change notifications. However the DemoCustomer1 type// in the list does.public partial class Form3 : Form{// This button causes the value of a list element to be changed.private Button changeItemBtn = new Button();// This DataGridView control displays the contents of the list.private DataGridView customersDataGridView = new DataGridView();// This BindingSource binds the list to the DataGridView control.private BindingSource customersBindingSource = new BindingSource();public Form3(){InitializeComponent();// Set up the "Change Item" button.this.changeItemBtn.Text = "Change Item";this.changeItemBtn.Dock = DockStyle.Bottom;this.changeItemBtn.Height = 100;//this.changeItemBtn.Click +=//  new EventHandler(changeItemBtn_Click);this.Controls.Add(this.changeItemBtn);// Set up the DataGridView.customersDataGridView.Dock = DockStyle.Top;this.Controls.Add(customersDataGridView);this.Size = new Size(400, 200);}private void Form3_Load(object sender, EventArgs e){this.Top = 100;this.Left = 100;this.Height = 600;this.Width = 1000;// Create and populate the list of DemoCustomer objects// which will supply data to the DataGridView.BindingList<DemoCustomer1> customerList = new ();customerList.Add(DemoCustomer1.CreateNewCustomer());customerList.Add(DemoCustomer1.CreateNewCustomer());customerList.Add(DemoCustomer1.CreateNewCustomer());// Bind the list to the BindingSource.this.customersBindingSource.DataSource = customerList;// Attach the BindingSource to the DataGridView.this.customersDataGridView.DataSource =this.customersBindingSource;}// Change the value of the CompanyName property for the first// item in the list when the "Change Item" button is clicked.void changeItemBtn_Click(object sender, EventArgs e){// Get a reference to the list from the BindingSource.BindingList<DemoCustomer1>? customerList =this.customersBindingSource.DataSource as BindingList<DemoCustomer1>;// Change the value of the CompanyName property for the// first item in the list.customerList[0].CustomerName = "Tailspin Toys";customerList[0].PhoneNumber = "(708)555-0150";}}// This is a simple customer class that// implements the IPropertyChange interface.public class DemoCustomer1 : INotifyPropertyChanged{// These fields hold the values for the public properties.private Guid idValue = Guid.NewGuid();private string customerNameValue = String.Empty;private string phoneNumberValue = String.Empty;public event PropertyChangedEventHandler PropertyChanged;// This method is called by the Set accessor of each property.// The CallerMemberName attribute that is applied to the optional propertyName// parameter causes the property name of the caller to be substituted as an argument.private void NotifyPropertyChanged([CallerMemberName] String propertyName = ""){if (PropertyChanged != null){PropertyChanged(this, new PropertyChangedEventArgs(propertyName));}}// The constructor is private to enforce the factory pattern.private DemoCustomer1(){customerNameValue = "Customer";phoneNumberValue = "(312)555-0100";}// This is the public factory method.public static DemoCustomer1 CreateNewCustomer(){return new DemoCustomer1();}// This property represents an ID, suitable// for use as a primary key in a database.public Guid ID{get{return this.idValue;}}public string CustomerName{get{return this.customerNameValue;}set{if (value != this.customerNameValue){this.customerNameValue = value;NotifyPropertyChanged();}}}public string PhoneNumber{get{return this.phoneNumberValue;}set{if (value != this.phoneNumberValue){this.phoneNumberValue = value;NotifyPropertyChanged();}}}}
}

6、同步绑定

在 Windows 窗体中实现数据绑定期间,多个控件会绑定到同一数据源。 在某些情况下,可能需要采取额外的步骤来确保控件的绑定属性之间,以及它们和数据源之间保持同步。 在两种情况下,需要执行以下步骤:

  • 数据源未实现 IBindingList,因此生成类型为 ItemChanged 的 ListChanged 事件。

  • 数据源实现了 IEditableObject。

在前一种情况下,请使用 BindingSource 将数据源绑定到控件。 在后一种情况下,请使用 BindingSource 并处理 BindingComplete 事件,然后在相关的 BindingManagerBase 上调用 EndCurrentEdit。

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

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

相关文章

Linux下的文本编辑Vi/Vim

编辑文件 文本编辑器有很多&#xff0c;比如图形模式的gedit、OpenOffice 等&#xff0c;文本模式下的编辑器有vi、vim&#xff08;vi的增强 版本&#xff09;等。vi和vim是我们在Linux中最常用的编辑器。 gedit 类似于Windows下的记事本&#xff0c;很方便的去修改文本。 Op…

【C语言】指针

基本概念 在C语言中&#xff0c;指针是一种非常重要的数据类型&#xff0c;它用于存储变量的内存地址。指针提供了对内存中数据的直接访问&#xff0c;使得在C语言中可以进行灵活的内存操作和数据传递。以下是关于C语言指针的一些基本概念&#xff1a; 1. 指针的声明&#xff…

深入了解云原生:定义与特征解析

文章目录 一、云原生概述1.1 什么是云原生1.2 云原生组成要素1.3 补充资料 二、云原生的目标2.1 云原生关键目标2.2 云原生特性 三、云原生应用 VS 传统单体应用参考资料 一、云原生概述 1.1 什么是云原生 (1)云原生定义 云原生(Cloud Native) 是一种软件架构和开发方法论&a…

山西电力市场日前价格预测【2023-12-27】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-12-27&#xff09;山西电力市场全天平均日前电价为737.42元/MWh。其中&#xff0c;最高日前电价为1500.00元/MWh&#xff0c;预计出现在08:00~08:30。最低日前电价为313.03元/MWh&#xff…

【数值分析】乘幂法,matlab实现

乘幂法 一种求实矩阵 A {A} A 的按模最大的特征值&#xff0c;及其对应的特征向量 x i {x_i} xi​ 的方法&#xff0c;只能求一个。特别适合于大型稀疏矩阵。 一个矩阵的特征值和特征向量可以通过矩阵不断乘以一个初始向量得到。 每次乘完之后要规范化&#xff0c;防止上溢或…

Qt Creator可视化交互界面exe快速入门3

上一期介绍的通过Qt Creator的组件直接拖拽的方式完成了一个界面&#xff0c;这期介绍按钮的信号交互。 专有名称叫信号与槽 实现方法1&#xff1a; 鼠标右键选择转化为槽就会跳出这样的界面 选择第一个为单击信号。然后就会跳转到代码界面。多了on_pushButton_clicked()。 …

分页合理化是什么?

一、前言 只要是干过后台系统的同学应该都做过分页查询吧&#xff0c;前端发送带有页码&#xff08;pageNum&#xff09;和每页显示数量&#xff08;pageSize&#xff09;的请求&#xff0c;后端根据这些参数来提取并返回相应的数据集。在SpringBoot框架中&#xff0c;经常会使…

以社区为基石,IvorySQL逐步成为中国基础软件开源数据库产业重要一员

编者按&#xff1a;开源数据库技术&#xff0c;作为软件开发领域的一大趋势&#xff0c;正逐渐改变整个软件产业的面貌。在这个充满活力的领域中&#xff0c;瀚高股份的IvorySQL凭借其社区活跃度和影响力&#xff0c;已经成为中国基础软件开源数据库产业的重要一员。随着《2023…

TCP:IP原理

TCP/IP 原理 TCP/IP 协议不是 TCP 和 IP 这两个协议的合称&#xff0c;而是指因特网整个 TCP/IP 协议族。从协议分层模型方面来讲&#xff0c;TCP/IP 由四个层次组成&#xff1a;网络接口层、网络层、传输层、应用层。 网络访问层(Network Access Layer) 网络访问层(Network …

宏集方案 | 物联网HMI的关键驱动力—SCADA级功能库和控件库

来源&#xff1a;宏集科技 工业物联网 宏集方案 | 物联网HMI的关键驱动力—SCADA级功能库和控件库 原文链接&#xff1a;https://mp.weixin.qq.com/s/UEPtpTehdbFrw3MUCnuR2A 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; 01 前言 在这个数字化时代&#xff0c;物…

Java内存区域与内存溢出异常

Java与C++之间有一堵由内存分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来。 2.1 概述 对于从事C、C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的“皇帝”,又是从事最基础工作的劳动人民——即拥有每一个对象的“所有权”,又…

个性化定制的知识付费小程序,为用户提供个性化的知识服务,知识付费saas租户平台

明理信息科技知识付费saas租户平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和…

vscode中默认shell选择

terminal.integrated.defaultProfile.linux在vs的Preference的Settings里面搜索terminal.integrated.defaultProfile.linux&#xff0c;默认的应该是null&#xff0c;将其修改为bash即可。 linux———/bin/sh、 /bin/bash、 /bin/dash的区别

亚马逊云科技 re:Invent 2023 产品体验:亚马逊云科技产品应用实践 国赛选手带你看 Elasticache Serverless

抛砖引玉 讲一下作者背景&#xff0c;曾经参加过国内世界技能大赛云计算的选拔&#xff0c;那么在竞赛中包含两类&#xff0c;一类是架构类竞赛&#xff0c;另一类就是 TroubleShooting 竞赛&#xff0c;对应的分别为亚马逊云科技 GameDay 和亚马逊云科技 Jam&#xff0c;想必…

NPM简介与使用指南:打造前端开发的利器

前言&#xff1a; 在现代前端开发中&#xff0c;NPM&#xff08;Node Package Manager&#xff09;已经成为了不可或缺的工具。它是一个强大的包管理工具&#xff0c;为开发者提供了丰富的第三方库和工具&#xff0c;大大简化了项目的依赖管理和构建过程。本篇博客将介绍 NPM …

Redis——IO多路复用

一&#xff1a;文件描述符 每一个网络连接其实都对应一个文件描述符 二&#xff1a;IO多路复用是什么&#xff1f; IO多路复用类似一个规范和接口&#xff0c;落地实现是由 linux系统的 select -> poll -> epoll&#xff0c;就是说通过一种机制&#xff0c;可以监视多…

数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)

目录 一.树的概念 二.树中重要的概念 三.二叉树的概念 满二叉树 完全二叉树 四.二叉树的性质 五.二叉树的存储 六.二叉树的遍历 前序遍历 中序遍历 后序遍历 一.树的概念 树是一种非线性数据结构&#xff0c;它由节点和边组成。树的每个节点可以有零个或多个子节点…

【开题报告】基于SpringBoot的企业资产管理系统的设计与实现

1.选题背景 基于Spring Boot的企业资产管理系统的设计与实现选题背景主要源于现代企业对资产管理的需求。随着企业规模的扩大和业务的发展&#xff0c;各类资产的数量和种类都在不断增加&#xff0c;包括办公设备、电脑、软件许可证、车辆等。传统的手工记录和管理方式已经无法…

【Linux基础】5. 磁盘管理

文章目录 【 1. 查看磁盘空间 】1.1 df 查看空间利用大小1.2 du 查看目录所占空间大小 【 2. 打包、压缩 】2.1 tar -cvf 打包2.2 gzip 压缩 【 3. 解压缩、解包 】3.1 gunzip 解压缩3.2 tar -xvf 解包 【 1. 查看磁盘空间 】 1.1 df 查看空间利用大小 作用 查看整个文件系统…

c# 隐含类型var 转换为 DataTable

/// <summary> /// 隐含类型var 转换为 DataTable /// </summary> /// <typeparam name"T"></typeparam> /// <param name"array"></param> /// <returns></return…