Preface:
In the article "[. Net]: bindingsource usage mode-Data Binding BASICS (1 )」.
This section describes how to wrap an object property into a property object "propertydescriptor" and use it for access and monitoring changes.
Packaging the properties of a data object into a property object is the basis for data binding.
Here we will discuss the "Data Source" that will be used for data binding 」.
As described in most books, Data Binding interacts with databases through objects in ADO. Net to display and access data in the database.
In this architecture, the object in ADO. Net is a Data Binding data source.
Related materials: How to: Use the Windows form bindingsource component to sort and filter ADO. Net documents
Some data points out that data binding can also wrap Custom Data Objects for display and access of Custom Data Objects.
In this architecture, custom data objects are packaged as a Data Binding data source.
Related materials: data with ADO. NET and custom objects is tied to applications
Data Binding data sources have many different implementations and definitions.
For more information about the data, see data sources supported by Windows form and interfaces related to data binding.
This article briefly introduces several design and development data binding objects used to encapsulate data sources.
Allows software developers to have a basic understanding of the object operation mode when designing data binding-related program code.
Bindinglist :
You can find a large number of data source-defined interfaces for data binding in the relevant data provided in the previous article.
Data Source objects that can be implemented based on data files meet your needs, but this is a heavy workload.
In the system. componentmodel namespace, you can find the bindinglist <t> object.
Bindinglist <t> implements the main interface defined for the Data Binding data source.
In addition, bindinglist <t> is a generic category. Class t can be accepted as a custom data object.
Developers can use bindinglist <t> to wrap custom data objects into data sources.
First, create a custom data object
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; } }}
Then, create a datagridview, bindingnavigator, and bindingsource to fasten the data.
Finally, create a data source and fasten the data.
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 <County> _ bindinglist = new bindinglist <County> (); Public form1 () {initializecomponent (); // Add item County county1 = new county (); county1.countyid = 1; county1.countyname = "Taipei City"; county1.countydescription = "cannot afford"; _ bindinglist. add (county1); county county2 = new county (); county2.countyid = 2; county2.countyname = "xinbei City"; county2.countydescription = "still unable to afford"; _ bindinglist. add (county2); // data binding this. countybindingsource. datasource =_bindinglist ;}}}
Complete and view the results.
Note the addingnew event when using bindinglist <t>.
The addingnew event is used to notify you to create a new data object.
When a addingnew event is processed, bindinglist <t> is added to the newobject brought back by the addingnew event.
Modify this example
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 <County> _ bindinglist = new bindinglist <County> (); Public form1 () {initializecomponent (); // Add item County county1 = new county (); county1.countyid = 1; county1.countyname = "Taipei City"; county1.countydescription = "cannot afford"; _ bindinglist. add (county1); county county2 = new county (); county2.countyid = 2; county2.countyname = "xinbei City"; county2.countydescription = "still unable to afford"; _ 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 = "Taoyuan County "; county3.countydescription = "still cannot afford"; E. newobject = county3 ;}}}
After the compilation is executed, press the "+" button on the bindingnavigator to view the result.
If the addingnew event is not processed and the data object has a default constructor function, bindinglist <t> adds the data object's default constructor to create a new object.
Modify this example
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 = "Hsinchu City"; this. countydescription = "the park is invincible ";}}}
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 <County> _ bindinglist = new bindinglist <County> (); Public form1 () {initializecomponent (); // Add item County county1 = new county (); county1.countyid = 1; county1.countyname = "Taipei City"; county1.countydescription = "cannot afford"; _ bindinglist. add (county1); county county2 = new county (); county2.countyid = 2; county2.countyname = "xinbei City"; county2.countydescription = "still unable to afford"; _ bindinglist. add (county2); // data binding this. countybindingsource. datasource =_bindinglist ;}}}
After the compilation is executed, press the "+" button on the bindingnavigator to view the result.
If the addingnew event is not processed and the data object does not have a default build function, bindinglist <t> sets its allownew attribute to false and does not allow new objects.
Modify this example
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 <County> _ bindinglist = new bindinglist <County> (); Public form1 () {initializecomponent (); // Add item County county1 = new county (1); county1.countyname = "Taipei City"; county1.countydescription = "cannot afford"; _ bindinglist. add (county1); county county2 = new county (2); county2.countyname = "xinbei City"; county2.countydescription = "still unable to afford"; _ bindinglist. add (county2); // data binding this. countybindingsource. datasource =_bindinglist ;}}}
After compilation, you will find that you are prohibited from pressing the "+" button on the bindingnavigator.
Related materials: bindinglist (of T), bindingsource. addingnew
Itypedlist:
During data binding operations, data objects are parsed based on the data source, and the properties of the data objects are encapsulated into the properties object propertydescriptor.
For details about the operation mode, refer to [. Net]: bindingsource usage mode-Data Binding BASICS (1 ).
When developers need to use custom propertydescriptor for Attribute access display during data binding, implementing the itypedlist interface can replace the default operation process.
First, create a custom 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); } }}
Create a custom bindinglist that inherits bindinglist and implements itypedlist.
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel;namespace WindowsFormsApplication1{ public class SampleBindingList : BindingList<County>, 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<PropertyDescriptor> propertyDescriptorCollection = new List<PropertyDescriptor>(); // 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()); } } }}
Finally, modify the example in this article
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 = "Taipei City"; county1.countydescription = "cannot afford"; _ bindinglist. add (county1); county county2 = new county (); county2.countyid = 2; county2.countyname = "xinbei City"; county2.countydescription = "still unable to afford"; _ bindinglist. add (county2); // data binding this. countybindingsource. datasource =_bindinglist ;}}}
Complete and view the results.
Related materials: itypedlist, how to: implement itypedlist Interface