BindingSource Control Introduction
The BindingSource control describes the BindingSource control as one of the new controls provided by the. NET Framework 2.0. The BindingSource control establishes a connection to the data source and then establishes a binding relationship between the controls in the form and the BindingSource control to enable data binding, simplifying the process of data binding.
The BindingSource control is a channel that connects to the back-end database and is also a data source because the BindingSource control supports sending commands to the background database to retrieve data, and it supports accessing, sorting, and ordering data directly through the BindingSource control. Filter and update operations. The BindingSource control can automatically manage many binding issues.
The BindingSource control does not have a run-time interface and cannot be seen on the user interface.
The BindingSource control accesses the current record through the present property and accesses the entire data table through the List property.
The following table lists the main properties of the BindingSource control:
Property Description
AllowEdit indicates whether the record in the BindingSource control can be edited.
AllowNew indicates whether the AddNew method can be used to add records to the BindingSource control
AllowRemove indicates whether records can be deleted from the BindingSource control.
Count gets the number of records in the BindingSource control.
CurrencyManager gets the current record manager associated with the BindingSource control.
Current gets the active record in the BindingSource control
DataMember Gets or sets the specific data list or database table in the data source to which the connector is currently bound.
DataSource Gets or sets the data source to which the connector is bound.
Filter Gets or sets the expression used for filtering.
Item Gets or sets the record for the specified index.
Sort Gets or sets the column name used for sorting to specify the sort.
The current attribute and the Removecurrent, EndEdit, CancelEdit, add, and AddNew methods can be used to make edits to the present record.
The following table lists the main methods of the BindingSource control
Method description
Add adds an existing item to the internal list
CancelEdit Remove all elements from the list
EndEdit applies the pending changes to the underlying data source.
Find finds the specified item in the data source.
MoveFirst moves to the first item in the list.
MoveLast moves to the last item in the list.
MoveNext moves to the next item in the list.
MovePrevious moves to the previous item in the list.
Removecurrent removes the current item from the list.
If you are dragging a table from the [data source] to the form of the DataGridView and data generated, then use VS05 automatically generated bindingnavigator to increase, delete, change. Usually you don't even have to write a single line of code. In addition, starting from VS05 it is strongly recommended to use BindingSource as the middle tier between controls and data. That is, the control is bound to BindingSource, and the BindingSource is then bound to the data object (date item) or to the list of objects (data item). There are many advantages to doing so. Bindingsource.endedit (); commits an update to an object or list of objects (such as a dataset) in memory. The Bindingsource.update method submits the update to the database.
Take Vs2005 operation Access2003 Database as an example (without a wizard)
Build an Access 2003 file Db1.mdb build a table (person): Table structure as follows, enter some content
UID Auto-Numbering primary key
Name text
Age Number
Sex text
Vs2005 Build a WinForm, drag a DataGridView, button onto the form. Run it, and then copy the Db1.mdb to the debug directory. Add three members to a class:
Private DataTable DT;
Private BindingSource BS;
Private OleDbDataAdapter da;
Double-click Form1, in Form1_Load:
private void Form1_Load (object sender, EventArgs e)
{
TODO: This line of code loads the data into the table "Db1dataset.stu". You can move or remove it as needed.
This.stuTableAdapter.Fill (This.db1DataSet.stu);
OleDbConnection conn = new OleDbConnection ();
Conn. ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb";
OleDbCommand cmd = new OleDbCommand ();
Cmd. Connection = conn;
Cmd.commandtext = "SELECT * from person";
DT = new DataTable ();
da = new OleDbDataAdapter ();
Da. SelectCommand = cmd;
OleDbCommandBuilder cb = new OleDbCommandBuilder (DA);
Da. Fill (DT);
BS = new BindingSource ();
Bs. DataSource = DT;
Datagridview1.datasource = BS;
}
Double-click Button1, in Button1_Click.
private void Button1_Click (object sender, EventArgs e)
{
Da. Update (DT);
MessageBox.Show ("OK");
}
In my example,
Private BindingSource bs;//Removed
BS = new BindingSource ();
Bs. DataSource = DT;
Datagridview1.datasource = BS; can also not BindingSource, direct datasource=dt;
These three lines are changed into
DataGrid1.DataSource = DT;
---------
' Always ' remember: In an app that uses DataAdapter, you don't have to manually open the connection and close the connection.
That is, you should not see Conn.Open (), conn.close () or anything in your code at all.
Because DataAdapter will turn the connection on and off automatically for you.
Development of WinForm based on BindingSource
1. Introduction
The BindingSource component is a bridge between the data source and the control, and provides a number of APIs and event information for our use. Using these APIs, we can decouple code from a variety of specific types of data sources, and with these events we can gain insight into the changes in the data.
2. Simple Binding
DataTable myTable = Mytableadapter.getdata ();//CREATE TABLE
BindingSource mybindingsource= new BindingSource ();//Create BindingSource
DataGridView Mygrid = new DataGridView ();//Create GridView
Mygrid.datasource = mybindingsource;//Binds BindingSource to the GridView
mytable;//bind data to BindingSource
Note:
1) Binding to a DataTable is actually bound to the DataView provided by the DataTable. Each DataTable has a default DataView
2) DataView is the essence of binding, as its name is, it is the presentation of data in a DataTable. Therefore, the same DataTable can be
, build multiple DataView, and then you can implement different filtering and sorting methods for the same data, and display the DataTable from different sides. This also embodies a certain degree of MVC thought.
3) Bindingsouce can also be used as a container for data (which is actually a data reference) to be passed between different forms, enabling editing of the data in a popup form
3. Main fine Table
Take the data shown as an example:
1) Dataset:mydataset
2) datatable:parenttable, childtable, grandchildtable
3) Relation:fk_parent_child, Fk_child_grandchild
Binding parent Data
Parentbindingsource.datasource = myDataSet;
Parentbindingsource.datamember = "ParentTable";
M_grandparentgrid.datasource = M_grandparentbindingsource;
Binds the child data. Childbindingsource.datasource = parentbindingsource;//bound to "parent BindingSource" instead of parent table
Childbindingsource.datamember = "Fk_child_grandchild";//Bind to "parent-child relation"
Bind grandson data. Grandchildbindingsource.datasource = childbindingsource;//bound to "child BindingSource"
Grandchildbindingsource.datamember = "Fk_child_grandchild";//Bind to "child-sun relation"
This allows you to put 3 DataView on the form and distribute it to the 3 bindingsouce, which makes it easy to correlate the main fine table.
4. Data ManipulationTo manipulate the data, you first need to get the current data item. The current property of the BindingSource returns an object of type DataRowView (as DataView is the encapsulation of a DataTable, DataRowView is the encapsulation of a DataRow), which is the encapsulation of the data item of the present, You can change the type into the object you want.
DataRowView Currentrowview = mybindingsource.current;//Gets the current Rowview
CustomersRow Custrow = Currentrowview.row as customersrow;//type converted to current data item
String company = custrow.companyname;//using the current data item
string Phoneno = Custrow.phone;
5
. Use BindingSource to make data containers
BindingSource can also be used as a data container, even if it is not bound to a data source, and it has a list inside it that can hold the data.
5.1Add Method
Calling the Add method inserts a data item in the list of BindingSource. If the data is inserted for the first time, and no data is bound, then the type of data inserted determines the type of data in the list in the future.
Note:
1) inserting other types of objects at this time throws a InvalidOperationException exception
2) The list is refreshed when the DataSource property is set, resulting in data loss from the Add method added to the list
5.2AddNew Method
The AddNew method returns an object that contains the data type that the BINDINGSOURC holds, and if the data was not previously accommodated, the object is returned.
The AddNew method invokes the EndEdit method and commits the manipulation of the current data, and the new data item becomes the current item.
The AddNew method raises the AddingNew event, where you can assign a value to a data item, or create a new data item
private void Onaddingnew (object sender, AddingNewEventArgs e) {e.newobject = new mycustomobject ();/}
6
to sort, filter, and search data with BindingSource.
6.1 Sort
You can sort the data by assigning a sort expression to the Sort property
Mybindingsource.sort = "ContactName ASC";//Sort the Contanctname column by ASC
Mybindingsource.sort = "Region ASC, CompanyName DESC"//first by region, then by CompanyName sort
6.2 Find
The Find method looks for the specified attribute and keyword and returns the index int of the first matching object, index = M_customersbindingsource.find ("CompanyName", IBM);// Press CompanyName to find IBM if (Index! =-1) {mybindingsource.position = index;//location BindingSource}
6.3 Filter
You can filter the data by assigning an expression to the Filter property
M_customersbindingsource.filter = "Country = ' Germany '";//filter out the Data country attribute is Germany
7
. Monitoring data with Event7
. 1 Event
1) AddingNew
triggered when the AddNew () method is called.
2) BindingComplete
When the control completes the data binding trigger, the control has read the value of the current data item from the data source. This event is triggered when BindingSource is re-bound or the current data item changes
Note:
- When multiple controls are bound to the same data source, this event fires multiple times
3) currrentchanged
This event is triggered when the current data item changes. The situation where this event is triggered is as follows
- When the Position property is changed
- When you add or delete data
- DataSource or DataMember property is changed
4) currentitemchanged
triggered when the value of the current data item changes
5) DataError
Typically, when invalid data is entered, an exception is thrown by Currencymanage, which triggers this event.
6) positionchanged
This event is triggered when the position property is changed.
7) ListChanged
Triggered when the data set changes. The situation where this event is triggered is as follows
- adding, editing, deleting, or moving data item
When changing properties that affect the list behavior characteristics, such as the AllowEdit property
- When a list is replaced (tied to a new data source)
8
. Restricting data modification
BindingSource is not only the "bridge" between the data source and the control, but also the "gatekeeper" of the data source. With BindingSource, we can control the modification of the data.
Binidingsource AllowEdit, AllowNew, and AllowRemove properties can control client code and control modifications to the data
9
. Binding of complex data types
For a string type of data, binding directly to the text control, there are several cases for complex types
- For data of types such as datetime, image, they are stored in a format that is inconsistent with the display requirements.
- Sometimes you don't want to show the customer ID, but you want to show the customer name
- Null values in the database
9
. 1 Binding class
The key to solving the above problem is to understand the binding class and understand how it controls the data binding process.
DataTable table = customersdataset.customers;
Binds the TextBox's Text property to the table's CustomerID column customerIDTextBox.DataBindings.Add ("Text", table, "CustomerID", true);
The line above is equivalent to the following two lines of code
Binding customeridbinding = new binding ("Text", table, "CustomerID", true); CUSTOMERIDTEXTBOX.DATABINDINGS.ADD (customeridbinding);
As you can see from the code, the binding is the mediator between the data source (table) and the control (Customeridtextbox), which has the following functions
- Data is taken from the data source and formatted according to the data type required by the control (formatting), and then passed to the control
- Fetch data from the control and parse it (parsing) according to the data type requirements of the data source, and then return to the data source
- Automatic format conversion of data
9.2Binding class constructors and properties
The binding constructor has multiple overloaded versions, and the following describes its important parameters, which exist in the properties of the binding object. In the following section, parameter names and attribute names are listed to
1) formattingenabled (attribute formattingenabled)
- True,binding objects are automatically converted between the data source type and the type required by the control
- False, and vice versa
2) DataSourceUpdateMode
Determines when changes to a value on a control are committed back to the data source
3) Nullvalue
The value corresponding to DBNull, NULL, and nullab<t>.
4) formatString
Format conversion
5) FormatInfo
An object reference that implements the IFormatProvider interface, converted with a custom format
To learn how types are converted, learn about the type Conversions and Format providers related content. For the application of the above attribute, see the following introduction
9
. 3 Type conversions based on the built-in mechanism (attributes, parameters) of the binding class
The mechanism of type conversion can be controlled by a parameter, or property setting, when the binding class is constructed.
1) DateTime
Let's start with an example of a datetime type using the DateTimePicker control
Create binding, set Formattingenabled to True
BIRTHDATETIMEPICKER.DATABINDINGS.ADD ("Value", M_employeesbindingsource, "BirthDate", true);
Set to use custom format Birthdatetimepicker.format = Datetimepickerformat.custom;
Set format Birthdatetimepicker.customformat = "mm/dd/yyyy";
2) Numeric
SALARYTEXTBOX.DATABINDINGS.ADD ("Text", Employeesbindingsource, "Salary", True, Datasourceupdatemode.onvalidation, " <not specified> "," #.00 ");
The above code does the following processing
- Set Formattingenabled to True: represents automatic type conversion
- Set DataSourceUpdateMode to OnValidation:
- Set Nullvalue to "<not specified>": These dbnull are shown as, "<not specified>", while the user input, "<not specified>" when Data value is DBNull
- Set formatstring to "#.00": Value reserved 2 decimal places
9.4. Events
The main events of the binding and how to control the type conversions based on these events are described below.
Main events:
1) Format Event
Occurs before the control displays this data after fetching the data from the data source. In this event, the data type of the data source is converted to the data type required by the control.
2) Parse Event
Contrary to event. It occurs when the value of the control changes before the data is updated back to the data source. In this event, the data type of the control is converted to the data type required by the data source.
These two events provide a mechanism for us to control the data, which are declared as Converteventhandler types,
void Converteventhandler (object sender, ConvertEventArgs e);
There are two parameters, and the second parameter, ConvertEventArgs E, provides the data we want to formatting and parsing. It has two properties
- E.desiredtype is the target type for which the value is to be converted
- The E.value is the numeric value to convert. We can replace this value
9.5. Event-based type conversions
9.5.1 processing the format Event
void Oncountryfromformat (object sender, ConvertEventArgs e) {if (E.value = = NULL | | e.value = = dbnull.value) { Picturebox.image = null; Return }
The Countryid field of the data source is bound, so e. Value returns the ID number through which the corresponding data row is obtained countriesrow Countryrow = Getcountryrow ((int) e.value);
Will E. Value is assigned to CountryName, which displays the name E.value = Countryrow.countryname in the control; Data conversion
ImageConverter converter = new ImageConverter (); Picturebox.image = converter. ConvertFrom (Countryrow.flag) as Image; }
9.5.2 processing the format Event
void Oncountryfromparse (object sender, ConvertEventArgs e) {//need to look up the country information for the country NA Me exchangeratesdataset.countriesrow row = Getcountryrow (e.value.tostring ()); if (row = = null) {string error = "Country not Found"; M_errorprovider.seterror (M_countryfromtextbox, error); M_countryfro Mtextbox.focus (); throw new ArgumentException (error); } e.value = row. Countryid; }
10
Complete Data Editing
This is often the case when you enter or select some data in a control, and the associated data can be updated only when you leave the control in the current year. This problem is determined by the internal mechanism of the DataRow.
The DataRowView class implements the IEditableObject interface, which supports transactional editing of objects (you can roll back data before you finish editing). We use the BeginEdit () method to start data editing and submit the edits through the EndEdit () method.
Do not confuse the DataRowView EndEdit () with the AcceptChanges () method of the DataSet, DataTable, DataRow. The DataRow has the original and current versions, while the IEditableObject caching mechanism makes it transient version, and data modifications are not committed to the data source until the EndEdit () method is called. This is the underlying cause of the previous problem.
If the data you want to edit is immediately committed, the best place to call the EndEdit () function is the validated event. The Validate event is parsed the data entered by the control, and triggered by validate, triggering endedit () in this event notifies all controls bound to the same data source for data synchronization updates.
private void Oncountrytextvalidated (object sender, EventArgs e) {exchangeratesbindingsource.endedit ();}
Of course, the EndEdit () event is also triggered when the current data item changes
11
using AutoComplete
When you want the Texbbox or ComboBox to automatically prompt, you should learn the AutoComplete function. Let's take a textbox as an example to introduce the relevant steps
1) Set the AutoCompleteSource property of the TextBox: FileSystem, Historylist, recentlyusedlist
2) If you want to use a custom list, set the AutoCompleteSource property to CustomSource
3) Set AutoCompleteMode to SuggestAppend. This means that when you enter a partial character, the control prompts all similar data in the drop-down list
4) If you do not want to use the built-in cue source, you can create a list of the AutoCompleteStringCollection classes yourself,
5) After creating this list, assign it to the TextBox's Autocompletecustomsourc property
12
the life cycle of databinding
The DataSourceUpdateMode property of BindingSource is the key, it has the following three possible values, the following distribution takes the TextBox control as an example to describe the life cycle of this property not at the same time databinding
1) onvalidating (default value)
- The life cycle of databinding:
Textbox.leave, Textbox.validating, Binding.parse, textbox.validated
- If you set the control's CausesValidation property to False, the validating event will not occur
2) onpropertychanged
- The life cycle of databinding:
At this point, binding.parse is triggered every time the control value changes. For a TextBox control, Binding.parse is triggered every time a character is entered.
3) Never
The parse event does not fire at this point, which means that the control becomes read-only.
13
Child Parent Bindings
The main fine binding, which is actually a parent-child binding, is described earlier. Sometimes we want to be bound by a child to the parent, so let's implement this mechanism together. The key to implementing this mechanism is the event, which is the BindingSource currentchanged incident
private void Oncurrentchanged (object sender, EventArgs e) { //Get current sub-DataRow Exchangeratesdataset.exchangeratesrow CurrentRow = (Exchangeratesdataset.exchangeratesrow) ((DataRowView) m_exchangeratesbindingsource.current). row;
Gets the associated parent datarow exchangeratesdataset.countriesrow Fromcountryrow = Currentrow.countriesrowbyfk_excha Ngerates_countriesfrom; Exchangeratesdataset.countriesrow tocountryrow = Currentrow.countriesrowbyfk_exchangerates_countriesto;
Display information for parent DataRow
if (Fromcountryrow = null && Tocountryrow! = null) {M_fromcountrycombo.selectedvalue = from Countryrow.countryid; M_tocountrycombo.selectedvalue = Tocountryrow.countryid; }
}
14 binding to multiple copies of data
Sometimes we want to see the same data at different angles, when we need to bind to multiple copies of the same data. The key here is the CurrencyManager class, where each BindingSource manages a currencymanager. If multiple controls are bound to the same BindingSource, then there is only one currencymanager, so there is only one currentitem, which causes those controls bound to the same bindingsource to be refreshed synchronously. To solve this problem, we need multiple currencymanager, which means we can create multiple BindingSource and bind to the same data source.
9
. 5 Handling NULL Types
Here are two concepts to figure out,. NET is built with null types that represent the null types in the database, and their differences.
1). NET built-in null types
- Nullable, reference type
- Nuallable<t>, value type
2). NET is used to represent the null type in the database
- DBNull, which has a property value that can be used to determine if the data is DBNull
if (Northwinddataset.employees[0]. Country = = DBNull.Value) {//Handle null case here}
For strongly typed datasets
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 binding datasource.
1) When binding to Dataset/datatable, returns the DataRowView object.
Attention:
A) The return is not a dataset or DataTable or DataRow.
b) If you want to get the added data, type conversions are required
BS for you to create the BindingSource
DataRow row= (DataRow) ((DataRowView) BS. AddNew ()). Row;
c) When using TypedDataSet, the conversion method is similar to the above, only with Typeddatarow.
MyDataRow defines the Typeddatarow for you
MyDataRow row= (MyDataRow) ((DataRowView) BS. AddNew ()). Row;
BindingSource-based WinForm development