博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转载】[Windows Forms] : BindingSource使用模式 - Data Binding基础知识 (二)
阅读量:5926 次
发布时间:2019-06-19

本文共 13380 字,大约阅读时间需要 44 分钟。

前言 :

在文章「」。

 

介绍了如何将对象的属性包装成属性对象 「PropertyDescriptor」,并用它来做存取、监看变更等工作。

将数据对象的属性包装成属性对象是 Data Binding运作基础,在了解这个运作之后。
这边再来讨论,Data Binding时会用到的「数据源」。

 

在大部分的书里描述,Data Binding透过 ADO.NET里的对象与数据库做互动,用来显示及存取数据库内的数据。

在这架构下,ADO.NET里的物件是一种 Data Binding的数据源。
相关资料 :

 

也有一部份的数据提到的是, Data Binding也可以包装自定义数据对象,来做自定义数据对象的显示及存取。

在这架构下,自定义数据对象包装后也是一种 Data Binding的数据源。
相关资料 :

 

关于 Data Binding的数据源,细分下去有许多不同的实作与定义。

相关数据可以参考 : 、

 

本篇文章简略介绍,几个设计开发 Data Binding用来包装数据源用的相关对象。

让软件开发人员在设计 Data Binding相关程序代码时,能对对象运作模式有基础的理解。

 

BindingList :

在上列文章提供的相关数据里,能找到大量针对 Data Binding的数据源定义的接口。

照着数据文件可以实作出,符合自己需求的数据源对象,但这是一件工作量不小的工作。

 

在 System.ComponentModel命名空间里,可以找到 BindingList<T>这个物件。

BindingList<T>实作针对 Data Binding的数据源定义的主要接口。
并且 BindingList<T>是一个泛型类别,可以接受类别 T当作自定义数据对象。

 

开发人员可以使用 BindingList<T>,来将自定义数据对象包装成数据源。

首先建立自定义数据对象

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace WindowsFormsApplication1{    public class County    {        // Properties        public int CountyID { get; set; }        public string CountyName { get; set; }        public string CountyDescription { get; set; }        // Constructor        public County()        {            this.CountyID = 0;            this.CountyName = string.Empty;            this.CountyDescription = string.Empty;        }    }}

 

再来建立 DataGridView、BindingNavigator、BindingSource系结数据

 

最后建立数据源并系结数据

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication1{    public partial class Form1 : Form    {        BindingList
_bindingList = new BindingList
(); public Form1() { InitializeComponent(); // Add Item County county1 = new County(); county1.CountyID = 1; county1.CountyName = "台北市"; county1.CountyDescription = "买不起"; _bindingList.Add(county1); County county2 = new County(); county2.CountyID = 2; county2.CountyName = "新北市"; county2.CountyDescription = "还是买不起"; _bindingList.Add(county2); // Data Binding this.countyBindingSource.DataSource = _bindingList; } }}

 

完成,看成果。

 

使用 BindingList<T>有一个地方需要特别注意的,就是关于 AddingNew事件。

AddingNew事件,主要用来通知要建立一个新的数据对象。

 

当有处理 AddingNew事件,BindingList<T>会加入 AddingNew事件里带回的 NewObject。

修改本文范例为

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace WindowsFormsApplication1{    public class County    {        // Properties        public int CountyID { get; set; }        public string CountyName { get; set; }        public string CountyDescription { get; set; }        // Constructor        public County()        {            this.CountyID = 0;            this.CountyName = string.Empty;            this.CountyDescription = string.Empty;        }    }}

 

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication1{    public partial class Form1 : Form    {        BindingList
_bindingList = new BindingList
(); public Form1() { InitializeComponent(); // Add Item County county1 = new County(); county1.CountyID = 1; county1.CountyName = "台北市"; county1.CountyDescription = "买不起"; _bindingList.Add(county1); County county2 = new County(); county2.CountyID = 2; county2.CountyName = "新北市"; county2.CountyDescription = "还是买不起"; _bindingList.Add(county2); // EventHandler _bindingList.AddingNew += new AddingNewEventHandler(_bindingList_AddingNew); // Data Binding this.countyBindingSource.DataSource = _bindingList; } void _bindingList_AddingNew(object sender, AddingNewEventArgs e) { County county3 = new County(); county3.CountyID = 3; county3.CountyName = "桃园县"; county3.CountyDescription = "依然买不起"; e.NewObject = county3; } }}

 

编译执行后,按下bindingNavigator上的『+』按钮看成果。

 

当没有处理 AddingNew事件并且数据对象有默认建构函式,BindingList<T>会加入数据对象默认建构函式建立新对象。

修改本文范例为

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace WindowsFormsApplication1{    public class County    {        // Properties        public int CountyID { get; set; }        public string CountyName { get; set; }        public string CountyDescription { get; set; }        // Constructor        public County()        {            this.CountyID = 4;            this.CountyName = "新竹市";            this.CountyDescription = "园区无敌贵";        }    }}

 

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication1{    public partial class Form1 : Form    {        BindingList
_bindingList = new BindingList
(); public Form1() { InitializeComponent(); // Add Item County county1 = new County(); county1.CountyID = 1; county1.CountyName = "台北市"; county1.CountyDescription = "买不起"; _bindingList.Add(county1); County county2 = new County(); county2.CountyID = 2; county2.CountyName = "新北市"; county2.CountyDescription = "还是买不起"; _bindingList.Add(county2); // Data Binding this.countyBindingSource.DataSource = _bindingList; } }}

 

编译执行后,按下bindingNavigator上的『+』按钮看成果。

 

当没有处理 AddingNew事件并且数据对象没有默认建构函式,BindingList<T>会将自己的 AllowNew属性设定为 false,不允许新增对象。

修改本文范例为

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace WindowsFormsApplication1{    public class County    {        // Properties        public int CountyID { get; set; }        public string CountyName { get; set; }        public string CountyDescription { get; set; }        // Constructor        public County(int countyID)        {            this.CountyID = countyID;            this.CountyName = string.Empty;            this.CountyDescription = string.Empty;        }    }}

 

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication1{    public partial class Form1 : Form    {        BindingList
_bindingList = new BindingList
(); public Form1() { InitializeComponent(); // Add Item County county1 = new County(1); county1.CountyName = "台北市"; county1.CountyDescription = "买不起"; _bindingList.Add(county1); County county2 = new County(2); county2.CountyName = "新北市"; county2.CountyDescription = "还是买不起"; _bindingList.Add(county2); // Data Binding this.countyBindingSource.DataSource = _bindingList; } }}

 

编译执行后,会发现禁止按下bindingNavigator上的『+』按钮,不允许新增。

 

相关资料 : 、

 

ITypedList :

Data Binding在运作的时候,会依照数据源解析出数据对象,再将数据对象的属性包装成属性对象 PropertyDescriptor。

运作模式的相关数据可以参考 : 。

 

当开发人员要在 Data Binding时使用自定义 PropertyDescriptor来做属性的存取显示时,实作 ITypedList接口就可以取代默认的运作流程。

首先建立自定义 PropertyDescriptor

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel;namespace WindowsFormsApplication1{    public class SamplePropertyDescriptor : PropertyDescriptor    {        // Properties        private readonly PropertyDescriptor _component = null;        // Constructor        public SamplePropertyDescriptor(PropertyDescriptor component)            : base(component)        {            #region Require            if (component == null) throw new ArgumentNullException("component");            #endregion            _component = component;        }        // Properties        public override Type ComponentType        {            get            {                return _component.ComponentType;            }        }        public override TypeConverter Converter        {            get            {                return _component.Converter;            }        }        public override bool IsLocalizable        {            get            {                return _component.IsLocalizable;            }        }        public override bool IsReadOnly        {            get            {                return _component.IsReadOnly;            }        }        public override Type PropertyType        {            get            {                return _component.PropertyType;            }        }        // Methods        public override object GetValue(object component)        {            return (component as County).CountyDescription + "$$$$$$$$";        }        public override void SetValue(object component, object value)        {            _component.SetValue(component, (value as string).Replace("$$$$$$$$", string.Empty));        }                public override void ResetValue(object component)        {            _component.ResetValue(component);        }        public override bool CanResetValue(object component)        {            return _component.CanResetValue(component);        }        public override bool ShouldSerializeValue(object component)        {            return _component.ShouldSerializeValue(component);        }        public override object GetEditor(Type editorBaseType)        {            return _component.GetEditor(editorBaseType);        }        public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter)        {            return _component.GetChildProperties(instance, filter);        }        public override void AddValueChanged(object component, EventHandler handler)        {            _component.AddValueChanged(component, handler);        }        public override void RemoveValueChanged(object component, EventHandler handler)        {            _component.RemoveValueChanged(component, handler);        }    }}

 

再来建立继承 BindingList及实作 ITypedList的自定义BindingList

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel;namespace WindowsFormsApplication1{    public class SampleBindingList : BindingList
, ITypedList { public string GetListName(PropertyDescriptor[] listAccessors) { return typeof(County).Name; } public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) { if (listAccessors != null && listAccessors.Length > 0) { throw new InvalidOperationException(); } else { // Result List
propertyDescriptorCollection = new List
(); // Create foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(typeof(County))) { if (propertyDescriptor.Name == "CountyDescription") { propertyDescriptorCollection.Add(new SamplePropertyDescriptor(propertyDescriptor)); } else { propertyDescriptorCollection.Add(propertyDescriptor); } } // Return return new PropertyDescriptorCollection(propertyDescriptorCollection.ToArray()); } } }}

 

最后修改本文范例为

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace WindowsFormsApplication1{    public class County    {        // Properties        public int CountyID { get; set; }        public string CountyName { get; set; }        public string CountyDescription { get; set; }        // Constructor        public County()        {            this.CountyID = 0;            this.CountyName = string.Empty;            this.CountyDescription = string.Empty;        }    }}

 

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication1{    public partial class Form1 : Form    {        SampleBindingList _bindingList = new SampleBindingList();        public Form1()        {            InitializeComponent();            // Add Item            County county1 = new County();            county1.CountyID = 1;            county1.CountyName = "台北市";            county1.CountyDescription = "买不起";            _bindingList.Add(county1);            County county2 = new County();            county2.CountyID = 2;            county2.CountyName = "新北市";            county2.CountyDescription = "还是买不起";            _bindingList.Add(county2);            // Data Binding            this.countyBindingSource.DataSource = _bindingList;        }    }}

 

完成,看成果。

image 

相关资料 : 、


期許自己~

能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。


 

 

转载于:https://www.cnblogs.com/yhlx125/articles/2458849.html

你可能感兴趣的文章
linux系统硬件配置查看方法
查看>>
白话PHP7扩展开发之创建对象
查看>>
mysql常用基础操作语法(一)~~对库的操作【命令行模式】
查看>>
Dubbo之旅--注册中心-Zookeeper
查看>>
统计某个路径下所有的java文件,以及统计代码数量
查看>>
[搜狗] 找一个字符串中包含全部出现字符的最小字符串
查看>>
支付宝分层与端到端回归平台建设实践
查看>>
数据库并行访问控制之互斥显示
查看>>
如何通过httpd和DVD ISO在RHEL上配置yum本地源
查看>>
《从零开始学Swift》学习笔记(Day 64)——Cocoa Touch设计模式及应用之目标与动作...
查看>>
[MySQL 学习] Innodb Optimistic Update流程
查看>>
GMap.Net开发之在WinForm和WPF中使用GMap.Net地图插件
查看>>
转 Vector的使用
查看>>
Python 终端下的TUI开发,whiptail 的 Python 封装
查看>>
一个使用EF进行查改的样例
查看>>
ViewPager+RadioGroup实现标题栏切换,Fragment切换
查看>>
笔试题目“检测IPv4地址”的实现
查看>>
返本求源——DOM元素的特性与属性
查看>>
iOS之github第三方框架(持续更新)
查看>>
OEA ORM 框架中的冗余属性设计
查看>>