I'm currently in the process of developing an object relation mapper for use with Microsoft SQL Server. During this process, I've been faced with a number of challenges related to the fact that I will be working with objects rather than datatables. If you've ever tried binding a datagrid to a list of objects, I'm sure you have come across the problem where you wanted to display properties that are not part of the object type itself.
Example: You have a list of orders, but you would like to display the customer's name and billing address along with the properties belonging to the
This is normally referred to as nested property binding. Many people create special view objects when this becomes a necessity. I wanted a smoother solution and I wanted it design time. The component I've created derives from
Bindingsource and is called
ObjectBindingSource. As the name implies, the components are designed to be working with objects and not datasets/datatables. I'm not a great fan when it comes to using datasets in databinding scenarios so this has not been a concern of mine.
Below is a class diagram describing our simple domain model used in this example.
As you can see from the model, the
Order class has a
Customer and a
DeliveryAddress property. This simple order form allows selecting a customer for the order and displaying customer details using nested property binding. The
BillingAddress belongs to the customer and should not be editable here, but the
DeliveryAddress is specific to each order and should be editable.
The ITypedList Interface
After some research (on Google and CodeProject), I found out that the
ITypedList interface was the thing to inspect. This is a really simple interface although not so simple to implement. Basically what it does is provide a method for you to supply what properties belong to a particular type. I'm not going to talk about how to implement this interface as there are numerous articles on the topic here and on the Internet in general. So I started out creating my own special collection component, implementing
IBindingList and what not. It soon became clear that what I really wanted was some kind of
bindingsource that supported nested property accessors.
Extending the Standard BindingSource Component
In order to provide design time databinding there has to be a
BindingSource component present (or at least some component implementing
IBindingList). With this in mind I started to look into extending the standard
bindingsource and implement the support for nested properties. As it turns out
BindingSource already implements the
ITypedList interface and its methods are there for you to override. I extended the
BindingSource with a property called
BindableProperties which is a way for the developer to specify what properties should be exposed from this
bindingsource. Then all I needed to do was to replace the default implementation with my own taking the
BindableProperties into account. The
ITypedList.GetItemProperties seems to be called very often by the consumer, so I moved the creation of
propertydescriptors out of the method and created the list of descriptors only when something changed like the datasource or the datamember.
There is also another property called
AutoCreateObjects which we will discuss in a minute.
GetItemProperties is the most important method in the
ITypedList interface and here it is implemented by the
BindingSource component and then overridden in the
ObjectBindingSource component to provide custom/nested property descriptors.
public override PropertyDescriptorCollection GetItemProperties
if (_propertyDescriptors.Count > 0)
return new PropertyDescriptorCollection(_propertyDescriptors.ToArray());
If we take a look at this code snippet from
CreatePropertyDescriptors, it might be easier to understand:
foreach (BindableProperty bindableProperty in _bindableProperties)
PropertyDescriptor propertyDescriptor =
Attribute attributes = new Attribute[propertyDescriptor.Attributes.Count + 1];
attributes[attributes.Length - 1] =
new CustomPropertyAttribute(itemType, bindableProperty.Name, propertyDescriptor);
(bindableProperty.Name, propertyDescriptor, attributes,_autoCreateObjects));
On thing to notice is that a custom property descriptor is created (not shown here) even if the property is a member of the root object. This is because the
CustomPropertyDescriptor uses compiled
set accessors as opposed to regular reflection. We will look at the accessors in a minute.
If you look closely, you will notice that there is also some attribute stuff going on here. This is just a convenient way of preserving information about the real underlying object and property when using nested property binding. By looking at the
CustomPropertyAttribute you can easily find the origin of the nested property. If nested property binding is performed using the path
Order.Customer.BillingAddress.StreetAddress, the property name will translate
Customer_BillingAddress_StreetAddress and it will look as if it is a part of the
Order type. In an application Framework I'm working on, we perform localization on the domain model rather than on the UI components and then this information comes in very handy.
Fast Dynamic Property Access using IDynamicAccessor
The origin for the
DynamicAccessor comes from an article written by Herbrandson. Based on a wrapper class created by Joel Martinez at CodeCube.Net, I created a similar wrapper that suited my needs for a dynamic property accessor. The general idea is to make use of the
DynamicMethodCompiler present in the .Net 2.0 Framework. I'm not going to discuss this in detail, but the bottom line is that we get a compiled setter/getter for the property on the type we are setting or getting the value for. This has proven so useful to me in a number of scenarios that I've included this in my core library. My core library is by the way included in the download. There is a lot of code there not relevant to this article, but it was easier for me just to include it as a whole. Feel free to explore.
Anyway, back to setting and getting the values. There are two methods from the base class(
TypeDescriptor) that are essential when it comes to setting and getting the values from and to the underlying object. From what I have read about this topic, .NET actually uses reflection to
set the property values. Using the
IDynamicAccessor provides a dynamic compiled version of the setters and getters by using the
DynamicMethodCompiler feature in .NET 2.0. Under those circumstances, this code should perform significantly faster than regular reflection.
If you look at the
ObjectBindingSource properties, you will notice that there is another new property call
false). This property tells the
ObjectBindingSource components to automatically create the objects in the
propertypath when setting the values. Example:
Order.DeliveryAddress.StreetAddress. If the user enters a value for
StreetAddress in the Grid ,there is no guarantee that there will be a valid
DeliveryAddress on that object. If
AutoCreateObjects is set to
Address object will be created and assigned to
DeliveryAddress before actually setting the value. In order for this to work, the object should have a parameterless constructor.
public override object GetValue(object component)
object instance = GetNestedObjectInstance(component,_propertyPath,false);
if (instance != null)
The first thing we need to do is to get a reference to the object instance for which to retrieve the value. This is done by a call to
GetNestedObjectInstance providing the root object instance and the property path (example:
Customer.Address.StreetAddress) as arguments. The third parameter indicates if the method should autocreate missing objects as explained above. There is no need to do this in the
public override void SetValue(object component, object value)
object instance =
if (instance != null)
SetPropertyValue(instance, _originalPropertyDescriptor.Name, value);
Setting the value is done in a similar way, only this time we will take the
_autoCreateObjects option into account.
Using the ObjectBindingSource Component
You will be using the
ObjectBindingSource component in exactly the same way that you use the standard
BindingSource component. The only difference is that you can now edit the
BindableProperties collection to specify the properties you need to bind to.
Clicking on the
BindableProperties property will bring up this collection editor.
You should note that if an invalid property path is entered, there is no error indicating this. If an invalid property path is entered, the
Bindable properties are ignored and reverted to the
BindingSource's default implementation of the
ITypedList interface. Provided in the download is a sample application using the new
Points of Interest
- 4 Sep 2007: Initial version