datagridview - DataPropertyName

G

Guest

I have a datagridview that is bound to a cutom collection.
The classes contained in the custom collection have the properties that are
bound to the class . This works fine !
But if one of the properites exposes another object I would like to bind a
property of the sub object to the DataPropertyName this does not seem to
work.

eg main object customer
has a property called Address which is a contained object
inside object Address there is property call city.
so DataPropertyName = "Address.city"
does not work !
Any ides
 
J

Joanna Carter [TeamB]

"WayDownUnder" <[email protected]> a écrit dans le message de
news: (e-mail address removed)...

|I have a datagridview that is bound to a cutom collection.
| The classes contained in the custom collection have the properties that
are
| bound to the class . This works fine !
| But if one of the properites exposes another object I would like to bind a
| property of the sub object to the DataPropertyName this does not seem to
| work.
|
| eg main object customer
| has a property called Address which is a contained object
| inside object Address there is property call city.
| so DataPropertyName = "Address.city"
| does not work !
| Any ides

I found the following code example from the DevEx support groups :

using System.ComponentModel;
using System;


namespace Intact.Evolution.Test
{
public class OrderPropertyDescriptor : PropertyDescriptor
{
public OrderPropertyDescriptor(string name) : base(name,
GetPropertyDescriptorAttributes(name)) { }

public override bool CanResetValue(object component)
{
return false;
}

public override Type ComponentType
{
get { return typeof(Order); }
}

public override object GetValue(object component)
{
Order order = component as Order;
if (order != null)
{
switch (this.Name)
{
case "Customer":
return order.Customer;
case "Name":
if (order.Customer != null)
return order.Customer.Name;
break;
case "Address":
if (order.Customer != null)
return order.Customer.Address;
break;
}
}
return null;
}

public override bool IsReadOnly
{
get { return false; }
}

public override System.Type PropertyType
{
get
{
switch (this.Name)
{
case "Customer":
return typeof(Customer);
case "Name":
return typeof(string);
case "Address":
return typeof(string);
}
return null;
}
}

public override void ResetValue(object component)
{
// empty method
}

public override void SetValue(object component, object value)
{
Order order = component as Order;
if (!IsReadOnly && order != null)
{
switch (this.Name)
{
case "Customer":
order.Customer = (Customer) value;
break;
case "Name":
order.Customer.Name = (string) value;
break;
case "Address":
order.Customer.Address = (string) value;
break;
}
}
}

public override bool ShouldSerializeValue(object component)
{
return false;
}

private static PropertyDescriptor GetPropertyDescriptor(string name)
{
foreach (PropertyDescriptor pd in
TypeDescriptor.GetProperties(typeof(Order)))
if (pd.Name == name)
return pd;

return null;
}

private static System.Attribute[] GetPropertyDescriptorAttributes(string
name)
{
PropertyDescriptor pd = GetPropertyDescriptor(name);

if (pd == null)
return null;

Attribute[] attributes = new Attribute[pd.Attributes.Count];

pd.Attributes.CopyTo(attributes, 0);

return attributes;
}

}
}

Then you need to add similar to the following in your list class

public class OrderList : GenericBindingList<Order>, ITypedList
{
public OrderList() : base(new List<Order>()) { }

public OrderList(List<Order> list) : base(list) { }

#region ITypedList Members

PropertyDescriptorCollection
ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
{
List<PropertyDescriptor> descriptors = new List<PropertyDescriptor>();

descriptors.Add(new OrderPropertyDescriptor("Customer"));
descriptors.Add(new OrderPropertyDescriptor("Name"));
descriptors.Add(new OrderPropertyDescriptor("Address"));

PropertyDescriptor[] propertyDescriptors = new
PropertyDescriptor[descriptors.Count];
descriptors.CopyTo(propertyDescriptors);
return new PropertyDescriptorCollection(propertyDescriptors);
}

string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
{
return String.Empty;
}

#endregion
}

This technique also means that you have to declare one PropertyDescriptor
for *every* property, nested or not, that you wish to surface. So, if you
don't specify PropertyDescriptors, you will see all non-nested properties,
if you add PropertyDescriptors you will only see the properties that you
supply :-(

We are looking at writing a generic descriptor to avoid those horrible case
statements.

Joanna
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top