Hi Robert,
ICustomTypeDescriptor is not required. You can create a custom TypeConverter that will provide your object dynamic properties at
runtime to be used by a PropertyGrid: Derive a class from System.ComponentModel.PropertyDescriptor to encapsulate your 'dynamic'
properties.
Here's an example of a custom TypeConverter you can use for an object name CustomObject:
public class CustomObjectTypeConverter : ExpandableObjectConverter
// ExpandableObjectConverter allows and instance of an object to which the
// CustomObjectTypeConverter class is applied using the TypeConverterAttribute
// to be expandable in the PropertyGrid when used as the Type of a property
// for another class.
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
return true;
return base.CanConvertTo (context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type
destinationType)
{
if (context == null)
throw new ArgumentNullException("context");
if (value is CustomObject && destinationType == typeof(string))
// this is the string value displayed in the PropertyGrid for an expandable object (+)
return string.Format("[{0}]", context.PropertyDescriptor.DisplayName);
return base.ConvertTo (context, culture, value, destinationType);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
if (context == null || !(context.Instance is CustomObject))
return base.GetPropertiesSupported(context);
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
CustomObject owner = value as CustomObject;
if (owner == null)
return base.GetProperties(context, value, attributes);
// return value declared here, filled in the foreach loop below
PropertyDescriptorCollection props = new PropertyDescriptorCollection(null);
// this line simply creates a collection of custom PropertyDescriptor objects
// for the owner (CustomObject).
CustomObjectDynamicProperties[] dynamicProps = owner.GetDynamicProperties();
foreach (PropertyDescriptor prop in dynamicProps)
{
// PropertyGrid doesn't check IsBrowsable for dynamic properties
// so you'll have to check that yourself:
if (prop != null && !prop.Attributes.Matches(new BrowsableAttribute(false)))
// Add the option
props.Add(prop);
}
return props;
}
}
--
Dave Sexton
Robert Ludig said:
I am using System.Windows.Forms.PropertyGrid to display the properties
of some custom objects. To enable dynamic modification of those
properties (and its attributes) this class hast to derive from
ICustomTypeDescriptor. Now I want those objects to be marshalled (by
reference) across process boundaries. So they can be viewed in a
propertygrid on a remote machine. Unfortunately ICustomTypeDescriptor
contains several types that are not serializable and not
marshalbyrefobjects. So types derived from ICustomTypeDescriptor can
never be serialized. Do you see any way how to support dynamic
properties in propertygrid AND being able to remote those objects ?