WinForms Databinding, Part 1

Posted on June 16, 2005

The basic idea behind databinding is simple. You have some source of data, and you have a control. When the data changes, you want the control to update to reflect the new value. When the control is changed (typically the control text), you want the data to change. Databinding is the term for the auto-magic process that does this.

Consider a form that contains a TextBox and an instance of a class that exposes some data:

public class DataBindingForm : Form
{
	private Invoice iv;
	private TextBox textBox1;
	private Button button1;
	
	// ...

	protected override void OnLoad(EventArgs e)
	{
		base.OnLoad(e);
		iv = new Invoice();
		iv.Amount = 500;
		this.textBox1.DataBindings.Add("Text", iv, "Amount");
	}
}

public class Invoice
{
	private int amt;
	public int Amount
	{
		get { return amt; }
		set { amt = value; }
	}
}

In the form’s OnLoad method, the Amount property of Invoice iv is linked to the Text property of textBox1. This linkage is recorded in an instance of the Binding class, which is added to the control’s DataBindings collection. The immediate effect of

this.textBox1.DataBindings.Add("Text", iv, "Amount");

is to set textBox1.Text to “500”. There are conceptually a few different types of bindings; the kind of binding I’m discussing here is a simple binding to an item data source.

After the initial binding, two things of interest may happen. The value of iv.Amount might change, and/or textBox1.Text might change. If the value of iv.Amount changes, we would hope that the TextBox text would change to match, and if the TextBox text was changed, that iv.Amount would be automatically updated.

Changing the Control Property

When the Validate event of textBox1 is raised, and textBox1.Text has been modified, the value is pulled from the TextBox property and applied to iv.Amount. More specifically, the Binding created in the call to this.textBox1.DataBindings.Add() adds handlers for the TextChanged and Validating events of the TextBox. If a property other than “Text” had being bound, for example, “BackColor”, the Binding instance would add a handler to the event of the same name as the property, plus Changed (e.g. “BackColorChanged”). When this xxxChanged event is raised, the Binding object knows that a subsequent Validate event raised by the control will require the updated property value to be pulled from the control and applied to the data source.

The Validate event is raised when focus leaves the control, so by default, the data source is not updated immediately when the control property changes. In our example, the user can happily type away in textBox1 without updating iv.Amount. When the user tabs to the next control in the tab order, however, Validate is raised, and the text value is applied to the data source (iv.Amount).

Changing the Data Source Value

One of the limitations of databinding in .NET 1.x is that an item data source must have special undocumented support to push changes in the data source back to the control. In our example above, if I were to change the value of iv.Amount, the text in textBox1 would not change.

In order to enable data binding from the data source back to the control (resulting in “two-way” data binding), the data source must provide a public event of type EventHandler, which the specific name of the bound property plus Changed. In our example, this would be “AmountChanged”. The event must be raised when the bound property of the data source is changed. This is the signal to the Binding instance that the control’s property must be updated. Our Invoice class would need to be revised as follows to push data changes back to the control:

public class Invoice
{
	private int amt;
	public event EventHandler AmountChanged;

	private void OnAmountChanged()
	{
		if (AmountChanged != null)
			AmountChanged(this, EventArgs.Empty);
	}
	
	public int Amount
	{
		get
		{
			return amt;
		}
		set
		{
			amt = value;
			OnAmountChanged();
		}
	}
}

With these changes, programmatic changes to iv.Amount will result in automatic updates to textBox1.Text.

In my next post, I’ll discuss the facilities for converting data between the data formats of the control property and that of the data source. For example, in the code shown above, the Invoice Amount property is an integer. The text in the TextBox may not be convertible to an integer value. What then?


No Replies to "WinForms Databinding, Part 1"


    Got something to say?

    Some html is OK