Ganz zu Beginn meiner Versuche mit .NET hatte ich schon einmal den Wunsch gehabt, in einem PropertyGrid beliebige Werte anzuzeigen, ohne vorher jeden Wert einzeln als Property mit getter/setter zu implementieren.
Damit eine Klasse selbst definieren kann, welche Werte im PropertyGrid angezeigt werden, muss ICustomTypeDescriptor implementiert werden.
Das wird jetzt hier ein wenig lang, aber ich sonst müsste man das zum Download anbieten.
//TODO: Diesen Code z.B. im Konstruktor (nach InitializeComponent()) einfügen
//KeyValueDescriptor erzeugen
KeyValueDescriptor myKeyValueDesc = new KeyValueDescriptor();
myKeyValueDesc.Add("Key", "Value", "Categorie");
//Klasse die ICustomTypeDescriptor implementiert
public class KeyValueDescriptor : ICustomTypeDescriptor
{
public PropertyDescriptorCollection props;
public object this [string name]
{
get {
return props[name];
}
}
public KeyValueDescriptor()
{
props = new PropertyDescriptorCollection(null );
}
public void Add(string name, object value )
{
props.Add(new CustomPropertyDescriptor(name, value ));
}
public void Add(string name, object value , string category)
{
props.Add(new CustomPropertyDescriptor(name, value , category));
}
#region ICustomTypeDescriptor Members
public object GetPropertyOwner(PropertyDescriptor pd)
{
return this ;
}
EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents()
{
return new EventDescriptorCollection(null );
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return new EventDescriptorCollection(null );
}
public AttributeCollection GetAttributes()
{
return new AttributeCollection(null );
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return props;
}
PropertyDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetProperties()
{
return props;
}
public TypeConverter GetConverter()
{
return null ;
}
public string GetComponentName()
{
return null ;
}
public object GetEditor(Type editorBaseType)
{
return null ;
}
public PropertyDescriptor GetDefaultProperty()
{
return null ;
}
public EventDescriptor GetDefaultEvent()
{
return null ;
}
public string GetClassName()
{
return null ;
}
#endregion
}
//Eigener PropertyDescriptor
public class CustomPropertyDescriptor : PropertyDescriptor
{
private object value ;
private string name;
private string description;
private string category;
private Type type;
public object Value
{
get
{
return this .value ;
}
}
public override string Name
{
get
{
return this .name;
}
}
public override string ToString()
{
if (this .value is String)
return (string ) this .value ;
else
return base .ToString();
}
public CustomPropertyDescriptor(string name, object value ) : this (name, value == null ? typeof (string ) : value .GetType())
{
this .value = value ;
}
public CustomPropertyDescriptor(string name, object value , string category) : this (name, value == null ? typeof (string ) : value .GetType())
{
this .value = value ;
this .category = category;
}
public CustomPropertyDescriptor(string name, Type type) : base (name, null )
{
this .name = name;
this .type = type;
}
public override string DisplayName
{
get
{
return this .name;
}
}
public override Type ComponentType
{
get
{
return null ;
}
}
public override bool IsReadOnly
{
get
{
return false ;
}
}
public override string Description
{
get
{
return this .description;
}
}
public override string Category
{
get
{
return this .category;
}
}
public override Type PropertyType
{
get
{
return type;
}
}
public override bool CanResetValue(object component)
{
return false ;
}
public override void ResetValue(object component)
{
}
public override object GetValue(object component)
{
return value ;
}
public override void SetValue(object component, object value )
{
this .value = value ;
}
public override bool ShouldSerializeValue(object component)
{
return false ;
}
}