views:

25

answers:

1

I have created data sources from my objects in my project, some of which have other objects as members. When I want to bind a some objects to a data grid I would like to display some of the values from the member objects in the data grid as well but the examples I have come across seem to use an entire other datagrid or controls to display these member object values.

How can I combine these values into one data grid? (Preferably without creating a wrapping class) Can I achieve this with LINQ somehow?

Your help is greatly appreciated.

Thanks

P.S. C# or VB examples will do.

+1  A: 

There's no clean way to do this in WinForms. You have a couple of options, ranging from easiest to hardest:

LINQ

(Specifically here anonymous types).

You can do something like this:

dataGridView.DataSource = from x in dataSource
                          select new
                          {
                              Property = x.Property,
                              SubProperty = x.ObjectProperty.SubProperty // etc.
                          };

This is by far the simplest approach, but it's also one-way binding; you cannot update data using this mechanism. This will also give you no design-time support for the grid, as the property names can't be discovered at design time.

Wrapper Class

This, I'm assuming, you're familiar with. You create a class that wraps your actual data-bound class, passing through the properties and bringing up the "sub-properties" to the class level. For example:

public string SubProperty
{
    get { return yourObject.ObjectProperty.SubProperty; }
    set { yourObject.ObjectProperty.SubProperty = value; }
}

This will give you design-time support for the grid (assuming that you use a BindingSource component and properly set up an object data source for this object) and will allow for two-way binding. It does, however, require that you roll a wrapper class and create every property that you want to bind to.

Custom Type Descriptor

This is the most difficult, but it's also the most flexible, fastest, and cleanest (from an external API perspective). I won't go into the ins and outs of how to do this in this post, but there are articles available on this. I would link to the MSDN page on custom TypeDescriptors, but it's a little daunting and extends beyond the scope of what you're trying to do.

In short, you create a custom TypeDescriptor class that provides a list of PropertyDescriptor instances. These allow you complete control over the binding experience, rather than relying on reflection (as would be the case in either of the above two cases). This is a non-trivial amount of code, though, so you'll need to decide if this is what you really want to do before you set out to do it.

This is a pretty good introduction to the TypeDescriptor class and what it does. What you're interested here is the PropertyDescriptorCollection. You just need to return a PropertyDescriptor for every property you want to interact with, including nested properties.

Adam Robinson
Thanks Adam, this is what I feared. A link for the Custom Type Descriptor may actually be useful, if not now for future reference. Thanks again.
clawson
@clawson: See edit.
Adam Robinson