1. Introduction
BindingSourceComponents are a bridge between data sources and controls, and provide a large number of APIs and events for us to use. Using these APIs, We can decouple Code from various data sources. Using these events, we can gain insight into data changes.
2. Simple binding
DataTable myTable = myTableAdapter. GetData (); // create a Table
BindingSourceMyBindingSource = newBindingSource(); // CreateBindingSource
DataGridView myGrid = new DataGridView (); // create a GridView
MyGrid. DataSource = myBindingSource; // setBindingSourceBind to GridView
MyTable; // bind dataBindingSource
Note:
1) bind to the able, which is actually bound to the DataView provided by the DataTable. Each DataTable has a default DataView.
2) DataView is the essence of the binding. Just like its name, it represents the data of the DataTable. Therefore, you can
To construct multiple dataviews, and then implement different filtering and sorting methods for the same data to display the DataTable from different aspects. This also reflects some MVC ideas.
3) BindingSouce can also be transferred between different forms as a data (actually a Data Reference) container, so as to edit the data in the pop-up form.
3. master table
Image
Take the data shown as an example:
1) DataSet: myDataSet
2) DataTable: ParentTable, ChildTable, GrandChildTable
3) Relation: FK_Parent_Child, FK_Child_GrandChild
// Bind the parent data
ParentBindingSource. DataSource = myDataSet;
ParentBindingSource. DataMember = "ParentTable ";
M_GrandParentGrid.DataSource = m_GrandParentBindingSource;
// Bind the child data.
ChildBindingSource. DataSource = parentBindingSource; // bind to "parent"BindingSource", Not the parent Table
ChildBindingSource. DataMember = "FK_Child_GrandChild"; // bind to "Parent-Child Relation"
// Bind Sun Tzu data.
GrandChildBindingSource. DataSource = childBindingSource; // bind it to the "subBindingSource"
GrandChildBindingSource. DataMember = "FK_Child_GrandChild"; // bind it to "child-sun Relation"
In this way, you can place three dataviews on the Form and bind them to the three BindingSouce, which makes it easy to implement the association presentation of the primary table.
4. data manipulation
To manipulate data, you must first obtain the current data item.BindingSourceThe Current attribute of returns an object of the DataRowView type (just as DataView encapsulates DataRow), which encapsulates the Current data item, you can convert the data type to the desired object.
DataRowView currentRowView = myBindingSource. Current; // obtain the Current RowView
CustomersRow custRow = currentRowView. Row as CustomersRow; // type conversion to the current data item
String company = custRow. CompanyName; // use the current data item
String phoneNo = custRow. Phone;
5. UseBindingSourceData container
BindingSourceIt can also be used as a data container. Even if it is not bound to a data source, it has a list that can hold data.
5.1Add Method
When the Add method is calledBindingSourceInsert data items in the list. If the data is inserted for the first time, and no data is bound, the type of the inserted data determines the data type in the list in the future.
Note:
1) inserting another type object will throw an InvalidOperationException.
2) When the DataSource attribute is set, the list will be refreshed, resulting in loss of data added to the list by the Add method.
5.2AddNew Method
The AddNew method returns the data type objects of BindingSourc. If the data type is not included before, the Object is returned.
The AddNew method calls the EndEdit method and submits operations on the current data. The new data item becomes the current data item.
The AddNew method triggers the AddingNew event. You can assign values to data items or create new data items.
Private void OnAddingNew (object sender, AddingNewEventArgs e)
{
E. NewObject = new MyCustomObject ();//
}
6. UseBindingSourceSort, filter, and search data
6.1 Sort
Assign a Sort expression to the Sort attribute to Sort data.
MyBindingSource. Sort = "ContactName ASC"; // Sort the ContanctName column by ASC
MyBindingSource. Sort = "Region ASC, CompanyName DESC" // Sort by Region and CompanyName first
6.2 Find
The Find method searches based on specified attributes and keywords, and returns the Index of the First Matching object.
Int index = m_CustomersBindingSource.Find ("CompanyName", IBM); // search for IBM by CompanyName
If (index! =-1)
{
MyBindingSource. Position = index; // locateBindingSource
}
6.3 Filter
Assigns an expression to the Filter attribute to Filter data.
M_CustomersBindingSource.Filter = "Country = 'Germany"; // filter out the data whose Country attribute is Germany.
7. Use Event to monitor data
7.1 Event
1) AddingNew
Triggered when AddNew () method is called.
2) BindingComplete
Triggered when the Control completes data binding. This indicates that the control has read the value of the current data item from the data source. WhenBindingSourceThis event is triggered when the rebinding or the current data item changes
Note:
* When multiple controls are bound to the same data source, this event is triggered multiple times.
3) currsponchanged
This event is triggered when the current data item changes. The event is triggered as follows:
* When the Position attribute is changed
* When adding or deleting data
* When the DataSource or DataMember attribute is changed
4) CurrentItemChanged
Triggered when the value of the current data item changes
5) DataError
When invalid data is input, CurrencyManage throws an exception to trigger this event.
6) PositionChanged
This event is triggered when the Position attribute is changed.
7) ListChanged
Triggered when the data set changes. The event is triggered as follows:
* When adding, editing, deleting, or moving data items
When changing attributes that affect the List behavior features, such as the AllowEdit attribute
* Replace List (bind to new data source)
8. Restrict data modification
BindingSourceIt is not only a "bridge" between data sources and controls, but also a "Gatekeeper" for data sources ". PassBindingSourceYou can modify the data.
The AllowEdit, AllowNew, and AllowRemove attributes of BinidingSource can control the modification of data by client code and controls.
9. Binding of complex data types
For String type data, you can directly bind it to the Text control. For complex types, there are the following situations:
* For DateTime, Image, and other types of data, their storage formats are inconsistent with the display requirements.
* Sometimes, you do not want to display the customer ID, but the customer name
* Null value in the database
9.1 Binding class
The key to solving the above problems is to understand the Binding class and how it controls the data Binding process.
DataTable table = customersDataSet. MERs MERS;
// Bind the Text attribute of TextBox to the CustomerID column of table
CustomerIDTextBox. DataBindings. Add ("Text", table, "CustomerID", true );
// The above line of code is equivalent to the following two lines of code
Binding customerIDBinding = new Binding ("Text", table, "CustomerID", true );
CustomerIDTextBox. DataBindings. Add (customerIDBinding );
The Code shows that Binding is the intermediary between the data source (table) and the control (customerIDTextBox). It has the following functions:
* Retrieve data from the data source, format the data according to the data type required by the control, and then pass it to the control
* Retrieve data from the control, parse the data according to the Data Type Requirements of the data source, and return the data to the data source.
* Automatic format conversion of data
9.2Binding class constructor and attributes
The Binding constructor has multiple overloaded versions. The following describes important parameters that exist in the attributes of the Binding object. The parameter names and attribute names are listed below
1) formattingEnabled (attribute FormattingEnabled)
O true: the Binding object is automatically converted between the data source type and the type required by the control.
O false, and vice versa
2) performanceupdatemode
Determines when the value changes on the control are submitted back to the data source.
3) nullValue
Values of DBNull, null, and Nullab <T>.
4) formatString
Format Conversion
5) formatInfo
An object reference that implements the IFormatProvider interface. It is converted using a custom format.
To learn how to convert types, learn about Type Conversions and Format Providers. For the application of the above attributes, see the following introduction
9.3 type conversion based on Binding class's built-in mechanism (attributes and parameters)
You can control the type conversion mechanism by using parameters or attribute settings during Binding class construction.
1) DateTime
The following describes an example of the DateTime type, using the DateTimePicker control.
// Create a Binding and set formattingEnabled to true
BirthDateTimePicker. DataBindings. Add ("Value", m_EmployeesBindingSource, "BirthDate", true );
// Set to use custom format
BirthDateTimePicker. Format = DateTimePickerFormat. Custom;
// Set the format
BirthDateTimePicker. CustomFormat = "MM/dd/yyyy ";
2) Numeric
SalaryTextBox. DataBindings. Add ("Text", employeesBindingSource, "Salary", true, performanceupdatemode. OnValidation, "<not specified>", "#. 00 ");
The above Code does the following:
* Set formattingEnabled to true: Indicates automatic type conversion.
* Set performanceupdatemode to OnValidation:
* Set nullValue to "<not specified>": These DBNull values are displayed as "<not specified>". When you enter "<not specified>", the data value is DBNull.
* Set formatString to "#. 00": the value is retained with two decimal places.
9.4. Events
The following describes the main events of Binding and how to control type Conversion Based on these events.
Main events:
1) Format event
After obtaining data from the data source, the control displays the data. In this event, convert the Data Type of the data source to the data type required by the control.
2) Parse event
Unlike Event. It changes the control value before the data is updated back to the data source. In this event, convert the Data Type of the control to the data type required by the data source.
These two events provide a mechanism for us to control data. They are declared as ConvertEventHandler types,
Void ConvertEventHandler (object sender, ConvertEventArgs e );
There are two parameters. The second parameter ConvertEventArgs e provides data for formatting and parsing. It has two attributes.
* E. DesiredType is the target type for Numerical Conversion.
* E. Value is the Value to be converted. We can replace this Value
9.5. Event-based type conversion
9.5.1 Format Event processing
Void OnCountryFromFormat (object sender, ConvertEventArgs e)
{
If (e. Value = null | e. Value = DBNull. Value)
{
PictureBox. Image = null;
Return;
}
// Bind the CountryID field of the data source. Therefore, the ID number returned by e. Value is used to obtain the corresponding data row.
CountriesRow countryRow = GetCountryRow (int) e. Value );
// Assign e. Value to CountryName to display the name in the control.
E. Value = countryRow. CountryName;
// Data Conversion
ImageConverter converter = new ImageConverter ();
PictureBox. Image = converter. ConvertFrom (countryRow. Flag) as Image;
}
9.5.2 Format Event processing
Void OnCountryFromParse (object sender, ConvertEventArgs e)
{
// Need to look up the Country information for the country name
ExchangeRatesDataSet. CountriesRow row =
GetCountryRow (e. Value. ToString ());
If (row = null)
{
String error = "Country not found ";
M_ErrorProvider.SetError (m_CountryFromTextBox, error );
M_CountryFromTextBox.Focus ();
Throw new ArgumentException (error );
}
E. Value = row. CountryID;
}
10. Complete data editing
This situation often occurs when you enter or select data in a control. The associated data can be updated synchronously only when you leave the control that year. This problem is determined by the internal mechanism of DataRow.
The DataRowView class implements the IEditableObject interface and supports transactional editing of objects (data can be rolled back before you confirm that the editing is complete ). We use the BeginEdit () method to start data editing and use the EndEdit () method to submit and edit the data.
Do not confuse the EndEdit () of DataRowView with the AcceptChanges () method of DataSet, DataTable, and DataRow. DataRow has original and current versions, and the IEditableObject caching mechanism allows it to have a transient version. data modification is not submitted to the data source before the EndEdit () method is called. This is the internal cause of the problem.
If you want to submit the edited data immediately, the best place to call the EndEdit () function is the Validated event. The Validate event is triggered after the data is parsed input by the Control and triggered after the validate event. If this event triggers EndEdit (), it notifies all the controls bound to the same data source to implement data synchronization and update.
Private void OnCountryTextValidated (object sender, EventArgs e)
{
ExchangeRatesBindingSource. EndEdit ();
}
Of course, the EndEdit () event is also triggered when the current data item changes.
11 use AutoComplete
If you want the AutoComplete function to be automatically displayed in TexbBox or ComboBox, you should learn about it. The following uses TextBox as an example to describe the related steps.
1) set the AutoCompleteSource attribute of TextBox: FileSystem, HistoryList, RecentlyUsedList
2) If you want to use a custom list, set the AutoCompleteSource attribute to CustomSource.
3) set AutoCompleteMode to SuggestAppend. This means that when you enter some characters, the control will prompt all similar data in the drop-down list.
4) if you do not want to use the built-in prompt source, you can create a list of AutoCompleteStringCollection classes by yourself,
5) After creating this list, assign it to the AutoCompleteCustomSourc attribute of TextBox
12 lifecycle of DataBinding
BindingSourceThe performanceupdatemode attribute of is critical. It has the following three possible values. The following uses the TextBox control as an example to describe the lifecycle of DataBinding when this attribute is different.
1) OnValidating (default)
* Lifecycle of DataBinding:
TextBox. Leave, TextBox. Validating, Binding. Parse, TextBox. Validated
* If the CausesValidation attribute of the control is set to false, the Validating event will not occur.
2) OnPropertyChanged
* Lifecycle of DataBinding:
In this case, Binding. Parse is triggered every time the control value changes. For the TextBox Control, Binding. Parse is triggered every time a character is entered.
3) Never
At this time, the Parse event will not be triggered, that is, the control will become read-only.
13 child parent binding
The previous section describes master-slave binding, which is actually a parent-child binding. Sometimes we want to bind the child to the parent, and we will implement this mechanism together. The key to implementing this mechanism is Event, which isBindingSourceCurrentChanged event
Private void OnCurrentChanged (object sender, EventArgs e)
{
// Obtain the current subdatarow
ExchangeRatesDataSet. ExchangeRatesRow currentRow =
(ExchangeRatesDataSet. ExchangeRatesRow)
(DataRowView) m_ExchangeRatesBindingSource.Current). Row;
// Obtain the associated parent DataRow
ExchangeRatesDataSet. CountriesRow fromCountryRow =
CurrentRow. CountriesRowByFK_ExchangeRates_CountriesFrom;
ExchangeRatesDataSet. CountriesRow toCountryRow =
CurrentRow. CountriesRowByFK_ExchangeRates_CountriesTo;
// Display the parent DataRow Information
If (fromCountryRow! = Null & toCountryRow! = Null)
{
M_FromCountryCombo.SelectedValue = fromCountryRow. CountryID;
M_ToCountryCombo.SelectedValue = toCountryRow. CountryID;
}
}
14 multiple copies bound to data
If you want to view the same data from different angles, You need to bind multiple copies of the same data. The key here is the CurrencyManager class, eachBindingSourceManages a CurrencyManager. If multiple controls are bound to the sameBindingSourceThere is only one CurrencyManager, so there is only one CurrentItem, which causes these bindings to the sameBindingSourceControl. To solve this problem, we need multiple currencymanagers, that is, we can create multipleBindingSourceAnd bound to the same data source.
9.5 process Null type
There are two concepts to understand: the built-in Null type in. Net and the Null type in the database, and their differences.
1). Net built-in Null type
* Nullable, reference type
* Nuallable <T>, Value Type
2). Net is used to represent the Null type in the database.
* DBNull, which has an attribute Value that can be used to determine whether the data is DBNull
If (northwindDataSet. Employees [0]. Country = DBNull. Value)
{
// Handle null case here
}
For a strongly Typed Dataset
If (northwindDataSet. Employees [0]. IsCountryNull ())
{
// Handle null case here
}
1) AddNew () function: Used to add a piece of data. The return type is determined by the bound DataSource.
1) When bound to DataSet/able, the DataRowView object is returned.
Note:
A) The returned data is not DataSet, able, or DataRow.
B) If you want to obtain the added data, type conversion is required.
// Bs created for youBindingSource
DataRow row = (DataRow) (DataRowView) bs. AddNew (). Row;
C) When TypedDataSet is used, the conversion method is similar to the preceding one, but TypedDataRow is used.
// MyDataRow: The TypedDataRow
MyDataRow row = (MyDataRow) (DataRowView) bs. AddNew (). Row;