Monday, September 19, 2011

Windows Forms Data Binding - Simple Binding Example

With simple binding, the property on a control is bound to a single data source member. The data source will typically be a collection, an array, or a DataTable object. If the data source is a collection or an array, binding will occur with a property of an item in the collection or array. If the data source is a DataTable object, binding will occur with a DataColumn object of the DataTable object.

In this example, I will walk through the implementation of binding customer data to controls on a form. First, create a new Windows Application project in Visual Studio .NET 2003. Drag a GroupBox control to the form. Then drag three Label controls and three TextBox controls to the form inside the GroupBox control. Finally, drag four Button controls to the form outside.

the GroupBox control. Arrange and label the controls like the ones shown in the following
figure:


Name your controls as follows:
Group Box: _groupBox1
First Name Label : _firstNameLabel
Last Name Label: _lastNameLabel
Phone Number Label: _phoneNumberLabel
First Name Textbox: _firstNameTextBox
Last Name Textbox: _lastNameTextBox
Phone Number Textbox: _phoneNumberTextBox;
First Button: _firstButton
Previous Button: _previousButton
Next Button: _nextButton
Last Button: _lastButton

For each of the four buttons, add an event handler named Button_Navigate for the Click event. To dynamically associate the event handler with the events, use the following syntax:

_firstButton.Click += new EventHandler(this.Button_Navigate);

To do this declaratively, ensure that the Button controls are declared using the WithEvents keyword, and add a Handles clause that specifies each Button control’s Click event to the declaration of the Button_Navigate event handler, as shown here:

 private void Button_Navigate(object sender, EventArgs e)
        {
        }
Now, you need to define a Customer class. Create a new Visual Basic .NET class file and add the following code to it:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Customer
{
    private string _firstName;
    private string _lastName;
    private string _phoneNumber;
 
    public Customer(string firstName, string lastName, string phoneNumber)
    {   
        _firstName = firstName;
        _lastName = lastName;
        _phoneNumber = phoneNumber;
    }
    public string FirstName
    {
        get { return _firstName; }
    }
 
    public string LastName
    {
        get { return _lastName; }
    }
 
    public string PhoneNumber
    {
        get { return _phoneNumber; }
    }
}

For simplicity, this example only stores a customer’s name and phone number. In a production application, more properties would likely need to be implemented.

Inside the constructor of the Form1 class after the call to InitializeComponent, initialize an array of customers with some arbitrary values. Declare the array as Readonly since it will not be reassigned after initialization. Here is the code:

Private ReadOnly Customer[] _customers;
   
    public 
DummyClass() {
        
// This call is required by the Windows Form Designer.
        
InitializeComponent();
        
// Add any initialization after the InitializeComponent() call
        
_customers = new Customer[] {
                
new Customer("James""Henry""123-123-1234"),
                
new Customer("Bill""Gates""234-234-2345"),
                
new Customer("Tupac""Shakur""345-345-3456")};
    
}


Now bind all TextBox controls to the array, as shown here:

_customers = new Customer[] {
        
new Customer("James""Henry""123-123-1234"),
        
new Customer("Bill""Gates""234-234-2345"),
        
new Customer("Tupac""Shakur""345-345-3456")};
_firstNameTextBox.DataBindings.Add("Text", _customers, "FirstName");
_lastNameTextBox.DataBindings.Add("Text", _customers, "LastName");
_phoneNumberTextBox.DataBindings.Add("Text", _customers, "PhoneNumber");

Finally, you need to handle the Click event raised by the Button controls to provide navigation functionality, as shown here:

private void Button_Navigate(object sender, EventArgs e) {
        BindingManagerBase manager 
_groupBox1.BindingContext(_customers);
        if 
((sender == _firstButton)) {
            manager.Position 
0;
        
}
        
else if ((sender == _previousButton)) {
            manager.Position 
(manager.Position - 1);
        
}
        
else if ((sender == _nextButton)) {
            manager.Position 
(manager.Position + 1);
        
}
        
else if ((sender == _lastButton)) {
            manager.Position 
(manager.Count - 1);
        
}
    }


The Button_Navigate event handler handles the Click event for all four navigation buttons. This code first retrieves the BindingManagerBase object from the BindingContext object of _groupBox1. The  BindingManagerBase object is actually an instance of CurrencyManager. The code basically asks the BindingContext object to “give me the CurrencyManager for the _customers data source.” The CurrencyManger object changes its Position property when a button is clicked. As the Position property is changed, all bound controls are updated automatically.

Now, to understand the purpose of the BindingContext object, add another GroupBox control to the form and three more TextBox controls to this GroupBox control. Name these controls as follows:

Group Box: _groupBox2
First Name Label: _firstNameLabel2
Last Name Label: _lastNameLabel2
Phone Number Label: _phoneNumberLabel2
First Name Textbox: _firstNameTextBox2
Last Name Textbox: _lastNameTextBox2
Phone Number Textbox: _phoneNumberTextBox2
First Button: _firstButton2
Previous Button: _previousButton2
Next Button: _nextButton2
Last Button: _lastButton2

Attach the
Click event of each Button control to the same Button_Navigate event handler as before. Now data bind the second set of TextBox controls to the array, as shown here:

_customers = new Customer[] {
        
new Customer("James""Henry""123-123-1234"),
        
new Customer("Bill""Gates""234-234-2345"),
        
new Customer("Tupac""Shakur""345-345-3456")};
_firstNameTextBox.DataBindings.Add("Text", _customers, "FirstName");
_lastNameTextBox.DataBindings.Add("Text", _customers, "LastName");
_phoneNumberTextBox.DataBindings.Add("Text", _customers, "PhoneNumber");
_firstNameTextBox2.DataBindings.Add("Text", _customers, "FirstName");
_lastNameTextBox2.DataBindings.Add("Text", _customers, "LastName");
_phoneNumberTextBox2.DataBindings.Add("Text", _customers, "PhoneNumber");


Before you can actually see the advantage of the BindingContext object, you need to ensure that each set of TextBox controls “lives” in its own data binding context. To do this, you need to create a BindingContext object for each GroupBox control. Remember that by default, the form automatically creates a single BindingContext object for itself and all child controls. Here is the constructor after creating two new BindingContext objects:

_customers = new Customer[] {
        
new Customer("James""Henry""123-123-1234"),
        
new Customer("Bill""Gates""234-234-2345"),
        
new Customer("Tupac""Shakur""345-345-3456")};
_groupBox1.BindingContext = new BindingContext();
_groupBox2.BindingContext = new BindingContext();
_firstNameTextBox.DataBindings.Add("Text", _customers, "FirstName");
_lastNameTextBox.DataBindings.Add("Text", _customers, "LastName");
_phoneNumberTextBox.DataBindings.Add("Text", _customers, "PhoneNumber");
_firstNameTextBox2.DataBindings.Add("Text", _customers, "FirstName");
_lastNameTextBox2.DataBindings.Add("Text", _customers, "LastName");
_phoneNumberTextBox2.DataBindings.Add("Text", _customers, "PhoneNumber");


Now, each GroupBox control and any child controls have their own context for data binding. Even though the controls contained in both GroupBox controls may bind to the same data source, they will be bound using different CurrencyManager objects.

You can visualize how the TextBox controls are data bound and synchronized in the following diagram:


From the previous diagram, you can see that each GroupBox control has its own
CurrencyManager object for the Customers data source. Therefore, changing the Position property on the first CurrencyManager object will have no effect on the TextBox controls contained in the second GroupBox control. Similarly, changing the Position property on the second CurrencyManager object will have no effect on the TextBox controls contained in the first GroupBox control. Therefore, add the following code to the Button_Navigate event handler to manipulate the second CurrencyManager object:

private void Button_Navigate(object sender, EventArgs e) {
        BindingManagerBase manager 
_groupBox1.BindingContext(_customers);
        if 
((sender == _firstButton)) {
            manager.Position 
0;
        
}
        
else if ((sender == _previousButton)) {
            manager.Position 
(manager.Position - 1);
        
}
        
else if ((sender == _nextButton)) {
            manager.Position 
(manager.Position + 1);
        
}
        
else if ((sender == _lastButton)) {
            manager.Position 
(manager.Count - 1);
        
}
    }


Next :Windows Forms Data Binding - Data Binding Interfaces

No comments :

Post a Comment