Data Binding with Objects


There are always discussions about whether it is better to use XML, typed datasets, or business objects when working with data within an application. Everyone has their own reasons, but I have always preferred business objects. With a business object, you are working in a completely object-oriented model and you have complete control over implementing the business rules directly within the business object.

The problem has traditionally been that Visual Studio wouldn't let you graphically hook up data-bound controls to business objects. You had to do this programmatically at runtime, which eliminated the RAD benefits of the visual designers. It was still better than manually loading the controls with data in for loops, but it wasn't ideal either.

With Windows Forms 2.0 and the new data-binding components, you now get the ability to visually bind your controls to actual business objects through the Visual Studio designers. This is a huge benefit to those of us who are die-hard business object fans. It also works out quite nicely if you're using a tool that maps business objects to your database (ORM tools, relational mappers, or even Microsoft's ObjectSpaces library).

Object Data-Binding Basics

To start with, all you need is a business object. To follow along, create a new Windows Application called ObjectBinding and then add to the solution a new class library called BusinessObjects. Then you can create any business object you like. I created a class called Contact with a first name and last name. These business objects need a default constructor, and public properties that will represent the columns of data when presented in a grid format.

Now you need to add a reference from the ObjectBinding project to the BusinessObjects project and build the solution. The reason for this is that when you use the Data Source Wizard to add an Object Data Source, it browses compiled Assemblies, not source code files.

Open the Data Sources window and click the button to add a new data source. When prompted for the type of the data source you want, select Object and click Next. You will then see a dialog prompting you to select the assembly in which the business object class resides. Click the "+" sign to drill down into that assembly and locate the class that you want to use as a data source. Figure 37.6 shows the Data Source Wizard browsing to the Contact class.

Figure 37.6. The Data Source Configuration Wizard selecting an Object Data Source.


Now you have a Data Source that is actually an object. After adding the new data source to the form, the form also now has a new BindingSource component on it called contactBindingSource (if your class is called Contact). You can use that BindingSource to gain access to the underlying objects.

Using the IEditableObject and INotifyPropertyChanged Interfaces

Now that you have seen just how easy it is for you to bind your controls to business objects, you can bring your game up another level by implementing a couple of interfaces that are designed to make your business objects even more compatible with data binding facilities.

Using the INotifyPropertyChanged Interface

When you drag a business object from the Data Sources window onto a form, what you end up with is mostly one-way binding. The class instance to which the control is bound will have its values changed whenever the control value changes. However, the control may not automatically know when the value on the object changes.

To ensure that your business object tells bound controls whenever a property changes, you can have your class implement the INotifyPropertyChanged interface. Any class that implements this interface is required to publish an event called PropertyChanged to which bound controls (or any other class that is aware of the interface) can subscribe. In the set accessor of your property, you can write a few lines of code to make use of the event, as shown in the following example:

public string MyProperty {     get     {         return myProp;     }     set     {         if (myProp != value)         {             PropertyChanged(this,               new PropertyChangedEventArgs("MyProperty"));         }     } } 


Using the IEditableObject Interface

In addition to letting the user interface know when properties change, you can also allow your business objects to take part in simple commit-or-cancel edit operations. By implementing the IEditableObject interface, your class will expose the following methods:

  • BeginEdit Indicates that the user has begun an edit operation on your class

  • CancelEdit Indicates that the user cancelled the edit, informing your class to roll back the changes made since editing began

  • EndEdit Indicates that the user finished editing and would like to commit the changes

Listing 37.1 shows a Contact class that implements both the IEditableObject interface and the INotifyPropertyChanged interface.

Listing 37.1. A Class That Implements IEditableObject and INotifyPropertyChanged

using System; using System.ComponentModel; using System.Collections.Generic; using System.Text; namespace BusinessObjects {   public class Contact : INotifyPropertyChanged, IEditableObject   {     struct contactData     {       internal int id;       internal string firstName;       internal string lastName;     }     private bool editing = false;     private contactData currentContact;     private contactData oldContact;     public Contact()     {       currentContact = new contactData();       currentContact.id = -1;       currentContact.firstName = string.Empty;       currentContact.lastName = string.Empty;     }     private void NotifyPropertyChanged(string propName)     {        PropertyChanged(this, new PropertyChangedEventArgs(propName));     }     public int ID     {       get       {         return currentContact.id;       }       set       {         if (currentContact.id != value)         {           currentContact.id = value;           NotifyPropertyChanged("ID");         }       }     } public string FirstName {   get   {     return currentContact.firstName;   }   set   {     if (FirstName != value)     {       currentContact.firstName = value;       NotifyPropertyChanged("FirstName");     }   } } public string LastName {   get   {     return currentContact.lastName;   }   set   {     if (currentContact.lastName != value)     {       currentContact.lastName = value;       NotifyPropertyChanged("LastName");     }   } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion #region IEditableObject Members public void BeginEdit() {   if (!editing)   {       editing = true;       oldContact = currentContact;     }   }   public void CancelEdit()   {     if (editing)     {       currentContact = oldContact;       editing = false;     }   }   public void EndEdit()   {     if (editing)     {       oldContact = new contactData();       editing = false;     }   }   #endregion   } } 



Microsoft Visual C# 2005 Unleashed
Microsoft Visual C# 2005 Unleashed
ISBN: 0672327767
EAN: 2147483647
Year: 2004
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net