PropertyManager
The PropertyManager is used to identify and maintain the current property of an object.
PropertyManager derives from BindingManagerBase; but oddly, most of all of the base properties and methods are overridden
to do nothing. For instance, setting the Position property of the object has
no effect. Also, the AddNew and RemoveAt methods throw a NotSupportedException. Your
guess is as good as mine as to why this object was derived from BindingManagerBase. As of this writing, PropertyManager
is only used by the PropertyGrid. The PropertyGrid uses the current property
to raise events, display property descriptions, and invoke appropriate editors.
The following code shows how to return
a PropertyManager from the BindingContext:
Customer singleCustomer
= new Customer();
PropertyManager pm = this.BindingContext
[singleCustomer] as
PropertyManager;
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, array, or DataTable.
If the data source is a collection or array, the binding will occur on the
property of a collection item. If the data source is a DataTable,
the binding will occur on a DataColumn of the DataTable.
In an example, we will walk through the
implementation of binding customer data to controls on a form.
First, create a new Windows Form in Visual
Studio .NET. Drag a group box to the form. Then drag three labels and three text
boxes to the form. Finally, drag four buttons to the form. Your form should
look similar to the following:
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 for the Click event called Button_Navigate.
To do this manually, the syntax would be:
_firstButton.Click += new EventHandler(this.Button_Validate);
Now, we must define a Customer. Create
a new C# class file, and add the following:
public
class Customer
{
private String _
firstName;
private String _lastName;
public 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, we are only storing a customer's name and phone number.
Inside the constructor of the Form, we
will initialize an array of customers with some arbitrary values. We will
declare the array as readonly since we do not intend
to reassign the collection value.
privatereadonly Customer[] _customers = null;
public Form1()
{
InitializeComponent( );
_customers = new
Customer[]
{
new Customer("James",
"Henry", "123-123-1234"),
new Customer("Bill",
"Gates", "234-234-2345"),
new Customer("Tupac", "Shakur",
"345-345-3456"),
}
}
We will now data bind all text box controls
to the Customer array. This is illustrated as follows:
private readonly Customer[] _customers = null;
public Form1()
{
InitializeComponent();
_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, we must handle the Click event
of the buttons in order to provide navigation:
private void Button_Navigate(object sender, System.EventArgs
e)
{
BindingManagerBase manager = _groupBox1.BindingContext [_customers];
if (sender == _firstButton)
{
manager.Position = 0;
}
else if (sender == _previousButton)
{
manager.Position--;
}
else if (sender == _nextButton)
{
manager.Position++;
}
else if (sender == _lastButton)
{
manager.Position = manager.Count
1;
}
}
The Button_Navigate handler handles the Click event for all four navigation
buttons. In this code, we first retrieve the BindingManagerBase object from
the BindingContext of _groupBox1. The instance is actually a CurrencyManager
. We simply ask the BindingContext to "give me the CurrencyManager for
the _customers data source." The CurrencyManger changes its Position property,
depending on which button was clicked. As the Position is changed, all bound
controls are updated automatically.
Now, in order to demonstrate the purpose of the BindingContext, let's add another
group box to the form, and three more text boxes to this group box. 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
We will now data bind this second set
of text box controls to the Customer array. This is illustrated as follows:
privatereadonly Customer[] _customers = null;
public Form1()
{
InitializeComponent();
_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 we can actually see the advantage of the BindingContext, we must ensure
that each set of text boxes "lives" in its own binding context. To
do this, we must create a BindingContext for each group box. Remember that by
default, the Form automatically creates a single BindingContext for it and all
child controls. Here is the constructor after creating two new BindingContext
objects:
privatereadonly Customer[] _customers = null;
public Form1()
{
InitializeComponent();
_customers = new
Customer[]
{
new Customer("James",
"Henry", "123-123-1234"),
newCustomer("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");
_astNameTextBox2.DataBindings.Add("Text", _customers,
"LastName");
_phoneNumberTextBox2.DataBindings.Add("Text",
_customers, "PhoneNumber");
}
Now, each group box and any child controls
have their own context for data binding. Even through the controls in both
group boxes may bind to the same data source, they will be bound using different
CurrencyManager objects.
We can visualize how the text box controls
are data bound and synchronized in the following diagram:
From the diagram above, we can see that
each group box has its own CurrencyManager
for the Customers data source. Therefore, changing the Position property
on the first CurrencyManager will have no effect on the text boxes contained
in the second group box. And changing the Position property on the second
CurrencyManager will have no effect on the text
boxes contained in the first group box.
Comments
Be the first to write a comment
You must me logged in to write a comment.