hen you think of using data binding in .NET it’s always to structured data sources such as a DataSet, array, list etc. But in reality, you aren’t limited to data residing in databases. Using data binding in Windows Forms, you can bind to almost any structure that contains data. You can bind to an array of values that you calculate at run time, that you read from a file, or that derive from the values of other controls. This article will focus on binding properties of one control to properties of another control.
In traditional data binding, you typically bind the display property (for example, the text property of a TextBox control) to your data source. With the .NET framework, you also have the option of setting other properties via binding as well. In fact, you can bind any property of any control to your data source. You might use binding for:
- Setting the graphic of an image control.
- Setting the background color of one or more controls.
- Setting the size of controls.
|Figure 1. Windows Form with Controls: The Panel on this form changes behavior based on the status of the CheckBoxes.|
In other words, data binding becomes an automatic way of setting any runtime-accessible property of any control on the form.
Figure 1 shows a Windows Form with two CheckBoxes and a Panel control. The Panel has a TextBox and a ComboBox. Selecting ChekBox1 makes the Panel visible, and selecting CheckBox2 enables the Panel. To handle this scenario you would write code to check the state of the CheckBoxes and then manipulate the Panel state appropriately. For instance:
' Code to make the panel visibleIf CheckBox1.Checked = True Then Me.Panel1.Visible = TrueElse Me.Panel1.Visible = FalseEnd IfCode to enable the panelIf CheckBox2.Checked = True Then Me.Panel1.Enabled = TrueElse Me.Panel1.Enabled = FalseEnd IF
The above code would have to be called during the CheckBox.CheckChanged events.
Data binding simplifies this to just two lines of code. To make it work, download the ZIP file available with this article (see the link in the left column), and open the VS.NET 2003 DataBoundUI.sln solution file and the DataBoundUI.vb form file.
|Author’s Note: frmDataBoundUI.vb is the completed form that you should end up with after completing the instructions in this article.|
Add the following code to the Form’s load event after the comment “Add code for base binding”:
Me.Panel1.DataBindings.Add("Visible", CheckBox1, "Checked")Me.Panel1.DataBindings.Add("Enabled", CheckBox2, "Checked")
Hit F5 to run the project and try checking and unchecking the two CheckBoxes. Voila! Data binding saved you a considerable amount of time writing code.
Types of Data Binding
Windows Forms can take advantage of two types of data binding: simple binding and complex binding. Each offers different advantages.
Simple data binding is the ability of a control to bind to a single data element, such as a value in a column in a dataset table or a property of another control. Therefore, it is typically used with TextBoxes and Labels?controls that typically display only a single value. In fact, any property on a control can be bound to another property of a control.
Complex data binding is the ability of a control to bind to more than one data element. Controls that support complex binding include DataGrids, ListBoxes, and ErrorProviders.
In the Form example in Figure 1, I used simple data binding. I bound the Panel control to the enable property of CheckBox1. The visible property of the Panel and the checked property of the CheckBoxes are Boolean values, hence binding is achieved in a single statement. I shall later examine a complex scenario where both properties are not of the same type.
Me.Panel1.DataBindings.Add("Visible", CheckBox1, "Checked")
I added a data binding to the panel control via the DataBindings.Add method. The first parameter in the Add method specifies the Visible property of the Panel to which the binding needs to be added, the second property specifies the control (CheckBox1) to which to bind, and the last property specifies the property (Checked) of that control to bind to.
In the second line, I bound the enabled property of the Panel to the checked property of CheckBox2.
Me.Panel1.DataBindings.Add("Enabled", CheckBox2, "Checked")
What’s important to note is that two properties of the Panel were bound to two different controls’ properties.
Enhanced Data Binding
Let’s enhance this scenario, From a TextBox, a user is allowed to set the background color of the Form, which changes dynamically (see Figure 2).
|Figure 2. Enhanced Data Binding: Here, the user can change the background color of the form by typing a string into a TextBox.|
To accomplish this you might be tempted to use the following statement:
Me.DataBindings.Add("BackColor", TextBox1, "Text")
However if you run the program with this line of code, you’re going to get a casting error. Specifically “Invalid cast from System.String to System.Drawing.Color.” The error occurs because you’re trying to set the backcolor of the form to a text type whereas it’s expecting a color type. Remember that the control property being bound and the property to which it is being bound must always be of the same type.
There are three simple steps to solve the problem of mismatched property types.
Step 1: Declare a class-level binding object with events.
Private WithEvents BackColorBinding As Binding 'Class level'
This code defines a binding object called “BackColorBinding.” You need to place this code at the class level. Insert it after the comment “Declare BackColorBinding” in the file DataBound.vb.
Step 2: Create an instance of the binding object.
BackColorBinding = New Binding("BackColor", TextBox1, "Text")Me.DataBindings.Add(BackColorBinding)
This code creates a new instance of the binding object. You need to place it in the form load event. Insert it after the comment “Add code for BackColor Binding.” Its parameters specify that you are binding the BackColor property of the form to the Text property of TextBox1. Further, you are adding this binding object (BackColorBinding) to the Data Bindings collection of the form. In this case the properties being bound are not the same type; one is color and the other text. Hence, we need one more step.
Step 3: Add code to the binding object’s format event to return the required value.
The Binding.Format event occurs when the property of a control is bound to a data value. The format event occurs both when data is pushed from the data source into the control, and when the data is pulled from the control into the data source. In the former case, the binding uses the format event to put the formatted data into the control. It first parses the data using the parse event, and then formats it and pushes it into the control.
In this example, you don’t need to use the parse event, but the information is useful in understanding the event mechanism. In our case, you need to convert the type from text to the requisite type as required by the BackColor property of the form. Add the following code to the format event of the BackColorBinding object, or just paste the code after the form load event.
Private Sub BackColorBinding_Format(ByVal sender As Object, ByVal e As _System.Windows.Forms.ConvertEventArgs) Handles BackColorBinding.Format If e.Value = "Red" Then e.Value = Color.Red Return End If If e.Value = "Green" Then e.Value = Color.Green Return End If e.Value = Color.EmptyEnd Sub
If the user selects red or green as the back color, the ConvertEventArg is set to that value. Run the project to test the code.
The code in the earlier section is very rudimentary; the following code can handle any color name typed in TextBox1.
If (TypeOf (e.Value) Is String) Then Try e.Value = Color.FromName(CType(e.Value, String)) Catch ex As Exception e.Value = Color.Empty End Try ' make sure we got a known color. If not, return empty ' If (Not CType(e.Value, Color).IsKnownColor) Then e.Value = Color.Empty End IfEnd If
This code checks the user-entered value to make sure it is a string. Then the text is cast to a color type. Exceptions are handled accordingly.
What if you need to bind multiple controls in a chain? For example, imagine that you wanted to bind a ComboBox in your Panel to the Text Box. This in turn hooks up to the BackColor of the Form, creating a chain reaction.
I’ve added a number of color names to the ComboBox1 collection. The next step is to hook the ComboBox1 selected text property to the TextBox1 text property. You don’t need to bother binding between the TextBox1 selected text and the BackColor of the form as that has already been done in the earlier piece of code.
To the form load event, you need to add the following, after the comment ComboBoxBinding, in the DataBound.vb file:
Me.TextBox1.DataBindings.Add("Text", ComboBox1, "Text")
Unlike the earlier binding you added for the BackColor of the form, this is a simple data binding.
Hit F5 to run the application, and choose a color from the ComboBox. Your application should resemble Figure 3.
|Figure 3. Binding Multiple Controls: Here, the user can change the background color of the form by selecting a color from a ComboBox, which populates the TextBox used in Figure 2.|
Versed in Versatility
Data binding can be used for more than just data. There are many practical problems that data binding can solve.
For example, consider a data entry form where a user is entering an amount for money being withdrawn or spent for a particular item. On this form, the user’s cash balance is shown in varying colors: Orange if the balance is low and red if the balance is precariously low or under the account limit. Here you would alter the BackColor of the calculated balance TextBox depending on the value entered.
Similarly take an instance where users change their application settings, such as color, font, etc., using an options dialog. This kind of binding provides an instant preview and change the properties of your application on the fly. You could utilize a control like the PropertyGrid for this, but in simple scenarios it’s overkill.
Thanks to a very flexible, general implementation, the places where you can apply the data binding infrastructure are innumerable. With just a little practice and a little time, you’ll undoubtedly find many uses in your applications.