Databinding Controls to Nullable Types
Checking for null values manually is both tedious and error prone. Instead, you can use .NET 2.0 databinding to eliminate the manual check. Databinding controls to nullable types is slightly different than databinding to standard value types. You use the control's DataBindings collection to assign bindings to control properties; in other words, by binding a specific property of a control to a specific property of the PatientNullable type, the application will be able to update the control property from the type, or (because the binding can be two-way) the type property from the control.
But standard controls don't "understand" null values. One way to work around that problem is to create an extended TextBox class, adding code to perform null checks. Here's the source code for a NullableTextBox class that extends the TextBox class. It provides a bindable
Text property that overrides the
Text property of the base class:
public class NullableTextBoxControl : TextBox
{
[Bindable(true)]
public new int? Text
{
get
{
if (base.Text != String.Empty)
return new Nullable<int>(int.Parse(base.Text));
return new Nullable<int>(0);
}
set
{
if (value.HasValue == true)
{
base.Text = value.Value.ToString();
}
else
{
base.Text = null;
}
}
}
}
 | |
Figure 5. NullableTextBoxControl: This design-mode view of the sample form shows the NullableTextBoxControl in the Toolbox. |
After you compile the code, Visual Studio adds the NullableTextBoxControl component to your ToolBox.
To use it, replace the
txtBilledAmount TextBox control in the Windows Forms sample application with a NullableTextBoxControl named
ntxtBilledAmount. Simply drag and drop this control to the form in its design view as shown in
Figure 5.
To show the effect of the two-way binding, also add a Button control. When clicked, the button's
Click event code will display the current value of the
BilledAmount property stored in the PatientNullable instance.
You need to change the
GetNullablePatient() method in the application to reference the
ntxtBilledAmount NullableTextBox control instead of the
txtBilledAmount TextBox control. The rest of the method's code remains the same. Here's the altered code:
public void GetNullablePatient(int patientID)
{
patientNullable.GetPatient(patientID);
txtName.Text = patientNullable.Name.ToString();
txtAddress.Text = patientNullable.Address;
if (patientNullable.ContactPerson != null)
txtContact.Text = patientNullable.ContactPerson;
else
txtContact.Text = "No contact(s) available";
if (patientNullable.SSN.HasValue)
{
long ssn = (long)patientNullable.SSN;
txtSSN.Text = ssn.ToString();
}
else
txtSSN.Text = "0";
if (patientNullable.BilledAmount.HasValue)
{
int billedAmount = (int)patientNullable.BilledAmount;
ntxtBilledAmount.Text = patientNullable.BilledAmount;
}
else
ntxtBilledAmount.Text = null;
if(!patientNullable.BilledAmount.HasValue)
patientNullable.BilledAmount = 0;
}
A binding ensures that any change in the NullableTextBoxControl will cause a corresponding change in the
BilledAmount property's value and vice versa. Add a binding to the DataBindings collection of the
ntxtBilledAmount control to bind its
Text property to the
BilledAmount property of the PatientNullable class instance (called
patientNullable in the following code):
private void Form1_Load(object sender, EventArgs e)
{
GetNullablePatient(3);
this.ntxtBilledAmount.DataBindings.Add("Text",
patientNullable, "BilledAmount",true);
}
Finally, add the button
Click event code to display the current
BilledAmount value from the PatientNullable instance:
private void btnClick_Click(
object sender, EventArgs e)
{
int billedAmount =
(int)patientNullable.BilledAmount;
 | |
Figure 6. Bound Control: When you change the value in the Billed Amount control, clicking the button shows that the BilledAmount value in the bound PatientNullable instance has changed as well. |
MessageBox.Show(
"The Billed Amount is: " +
billedAmount.ToString(),
"Patient Information");
}
Now you can compile and execute the application. The initial output is similar to
Figure 4, but if you change the BilledAmount value in the TextBox and then click the Button shown beneath the TextBox controls you'll see a screen like
Figure 6.
Note that the BilledAmout property value (shown in the MessageBox in
Figure 6) gets updated automatically when you change the contents of the "Billed Amount" NullableTextBoxControl.
By now, you should see the advantages of using nullable types in your C# applications. Using them not only simplifies your code, but also eliminates a common source of run-time errors when assigning values from database columns that can contain nulls.