Data Binding


The previous examples have used the DataGrid and DataGridView controls, which form only a small part of the controls in the .NET runtime that can be used to display data. The process of linking a control to a data source is called data binding.

In MFC the process of linking data from class variables to a set of controls was termed Dialog Data Exchange (DDX). The facilities available within .NET for binding data to controls are substantially easier to use and also more capable. For example, in .NET you can bind data to most properties of a control, not just the text property. You can also bind data in a similar manner to ASP.NET controls (see Chapter 32, “ASP.NET Pages”).

Simple Binding

A control that supports single binding typically displays only a single value at once, such as a text box or radio button. The following example shows how to bind a column from a DataTable to a TextBox:

  DataSet ds = CreateDataSet(); textBox.DataBindings.Add("Text", ds , "Products.ProductName"); 

After retrieving some data from the Products table and storing it in the returned DataSet with the CreateDataSet() method as shown here, the second line binds the Text property of the control (textBox1) to the Products.ProductName column. Figure 29-13 shows the result of this type of data binding.

image from book
Figure 29-13

The text box displays a string from the database. Figure 24-14 shows how the SQL Server Management Studio tool could be used to verify the contents of the Products table to check that it is the right column and value.

image from book
Figure 29-14

Having a single text box on-screen with no way to scroll to the next or the previous record and no way to update the database is not very useful, so the following section shows a more realistic example, and introduces the other objects that are necessary for data binding to work.

Data-Binding Objects

Figure 29-15 shows a class hierarchy for the objects that are used in data binding. This section discusses the BindingContext, CurrencyManager, and PropertyManager classes of the System.Windows .Forms namespace, and shows how they interact when data is bound to one or more controls on a form. The shaded objects are those used in binding.

image from book
Figure 29-15

In the previous example, the DataBindings property of the TextBox control was used to bind a column from a DataSet to the Text property of the control. The DataBindings property is an instance of the ControlBindingsCollection shown in Figure 29-15:

  textBox1.DataBindings.Add("Text", ds, "Products.ProductName"); 

This line adds a Binding object to the ControlBindingsCollection.

BindingContext

Each Windows Form has a BindingContext property. Incidentally, Form is derived from Control, which is where this property is actually defined, so most controls have this property. A BindingContext object has a collection of BindingManagerBase instances (see Figure 29-16). These instances are created and added to the binding manager object when a control is data-bound.

image from book
Figure 29-16

The BindingContext might contain several data sources, wrapped in either a CurrencyManager or a PropertyManager. The decision on which class is used is based on the data source itself.

If the data source contains a list of items, such as a DataTable, DataView, or any object that implements the IList interface, a CurrencyManager will be used. A CurrencyManager can maintain the current position within that data source. If the data source returns only a single value, a PropertyManager will be stored within the BindingContext.

A CurrencyManager or PropertyManager is only created once for a given data source. If two text boxes are bound to a row from a DataTable, only one CurrencyManager will be created within the binding context.

Each control added to a form is linked to the form’s binding manager, so all controls share the same instance. When a control is initially created, its BindingContext property is null. When the control is added to the Controls collection of the form, the BindingContext is set to that of the form.

To bind a control to a form, an entry needs to be added to its DataBindings property, which is an instance of ControlBindingsCollection. The following code shown creates a new binding:

  textBox.DataBindings.Add("Text", ds, "Products.ProductName"); 

Internally, the Add() method of ControlBindingsCollection creates a new instance of a Binding object from the parameters passed to this method, and adds this to the bindings collection represented in Figure 29-17.

image from book
Figure 29-17

Figure 29-17 illustrates roughly what is going on when a Binding object is added to a Control. The binding links the control to a data source, which is maintained within the BindingContext of the Form (or control itself). Changes within the data source are reflected into the control, as are changes in the control.

Binding

This class links a property of the control to a member of the data source. When that member changes, the control’s property is updated to reflect this change. The opposite is also true - if the text in the text box is updated, this change is reflected in the data source.

Bindings can be set up from any column to any property of the control. For example, you can not only bind the text of a text box but also the color of that text box. It is possible to bind properties of a control to completely different data sources; for example, the color of the cell might be defined in a colors table, and the actual data might be defined in another table.

CurrencyManager and PropertyManager

When a Binding object is created, a corresponding CurrencyManager or PropertyManager object is also created, provided that this is the first time that data from the given source has been bound. The purpose of this class is to define the position of the current record within the data source, and to coordinate all list bindings when the current record is changed. Figure 29-18 displays two fields from the Products table, and includes a way to move between records by means of a TrackBar control.

image from book
Figure 29-18

The following example shows the main ScrollingDataBinding code:

  namespace ScrollingDataBinding {   partial class Form1: Form   {     public Form1()     {       InitializeComponent();     }     private DataSet CreateDataSet()     {       string customers = "SELECT * FROM Products";       DataSet ds = new DataSet();       using (SqlConnection con = new SqlConnection (                ConfigurationSettings.                ConnectionStrings["northwind"].ConnectionString))       {         SqlDataAdapter da = new SqlDataAdapter(customers, con);            da.Fill(ds, "Products");       }       return ds;     }     private void trackBar_Scroll(object sender, EventArgs e)     {         this.BindingContext[ds, "Products"].Position = trackBar.Value;     }        private void retrieveButton_Click(object sender, EventArgs e)     {       retrieveButton.Enabled = false;       ds = CreateDataSet();          textName.DataBindings.Add("Text", ds, "Products.ProductName");       textQuan.DataBindings.Add("Text", ds, "Products.QuantityPerUnit");       trackBar.Minimum = 0;       trackBar.Maximum = this.BindingContext[ds, "Products"].Count - 1;       textName.Enabled = true;       textQuan.Enabled = true;       trackBar.Enabled = true;     }     private DataSet ds;   } } 

The scrolling mechanism is provided by the trackBar_Scroll event handler, which sets the position of the BindingContext to the current position of the track bar thumb - altering the binding context here updates the data displayed on the screen.

Data is bound to the two text boxes in the retrieveButton_Click event by adding a data binding expression - here the Text properties of the controls are set to fields from the data source. It is possible to bind any simple property of a control to an item from the data source; for example, you could bind the text color, enabled, or other properties as appropriate.

When the data is originally retrieved, the maximum position on the track bar is set to be the number of records. Then, in the scroll method, the position of the BindingContext for the products DataTable is set to the position of the scroll bar thumb. This changes the current record from the DataTable, so all controls bound to the current row (in this example, the two text boxes) are updated.

Now that you know how to bind to various data sources, such as arrays, data tables, data views, and various other containers of data, and how to sort and filter that data, the next section discusses how Visual Studio has been extended to permit data access to be better integrated with the application.




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net