|
Registriert seit: 10. Jun 2004 Ort: Garching (TUM) 4.579 Beiträge |
#10
So, falls das nochmal wen interessiert, hier meine Lösung:
Der Graph (Containerklasse für Kanten und Knoten) implementiert das Interface ICustomTypeDescriptor - damit kann man dynamisch Zeilen im PropertyGrid hinzufügen. Ein Feld in der Klasse dient als Sammelbecken für alle nicht-erkannten Attribute:
Code:
Dann muss man mindestens eine Methode wie folgt überschreiben:
private List<XAttribute> Attrib;
Code:
Den Rest kann man einfach weiterleiten:
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{ var normal = TypeDescriptor.GetProperties(this, attributes, true); var all = new List<PropertyDescriptor>(normal.Count + Attrib.Count); foreach (PropertyDescriptor item in normal) { all.Add(item); } foreach (var item in Attrib) { if (VariantDescriptor.Supports(item)) { all.Add(new VariantDescriptor(item)); } } return new PropertyDescriptorCollection(all.ToArray()); }
Code:
Und hier kommt der Interessante Teil: Der PropertyDescriptor der das typsichere Bearbeiten ermöglicht:
public string GetClassName()
{ return TypeDescriptor.GetClassName(this, true); } public string GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(this, true); } /// etc...
Code:
Wenn jetzt ein objekt der Klasse graph einem properyGrid zugewiesen wird, erscheinen die zusätzlichen Attribute wie normale Eigenschaften und sind ebenso editierbar. Typsicherheit ist gegeben (z.B. "100000" ist kein gültiger wert für System.Short)
/* Diese Klasse leistet die Darstellung der verschidenen XAttribute
* im PropertyGrid. Es werden einfache Typen unterschieden, und zum * Editieren in ihre C#-Equivalente überführt. * Getestet mit int, float, double, decimal, string und DateTime, ggf. switches erweitern. * Unbekannte Typen sollen nicht editierbar gemacht werden, * wenn TypeCodeToType() den Wert null zurückgibt. (kann mit Supports() geprüft werden) * * Klasse benötigt Schema-Infos. * */ class VariantDescriptor : PropertyDescriptor { private XAttribute attr; private XmlTypeCode type; public VariantDescriptor(XAttribute attribute) : base(attribute.Name.ToString(), null) { attr = attribute; var info = attr.GetSchemaInfo(); if (info == null) throw new ArgumentException("Schema-Info is required!\r\nUse XDocument.Validate(..., ..., true) or equivalent."); type = attr.GetSchemaInfo().SchemaType.TypeCode; if (TypeCodeToType(type) == null) throw new NotImplementedException(string.Format("This type (\"{0}\") is not supported.", type.ToString())); } public override bool CanResetValue(object component) { return false; } public override Type ComponentType { get { return typeof(Graph); } } public override object GetValue(object component) { switch (type) { case XmlTypeCode.Time: case XmlTypeCode.Date: case XmlTypeCode.DateTime: return XmlConvert.ToDateTime(attr.Value, XmlDateTimeSerializationMode.RoundtripKind); // Konvertierung nötig, um das Dezimaltrennzeichen korrekt zu wandeln case XmlTypeCode.Decimal: return XmlConvert.ToDecimal(attr.Value); case XmlTypeCode.Double: return XmlConvert.ToDouble(attr.Value); case XmlTypeCode.Float: return XmlConvert.ToSingle(attr.Value); default: return attr.Value; } } public override bool IsReadOnly { get { return false; } } public override Type PropertyType { get { return TypeCodeToType(type); } } private static Type TypeCodeToType(XmlTypeCode TypeCode) { switch (TypeCode) { case XmlTypeCode.Boolean: return typeof(Boolean); case XmlTypeCode.UnsignedByte: case XmlTypeCode.Byte: return typeof(byte); case XmlTypeCode.Date: case XmlTypeCode.Time: case XmlTypeCode.DateTime: return typeof(DateTime); case XmlTypeCode.Decimal: return typeof(decimal); case XmlTypeCode.Double: return typeof(double); case XmlTypeCode.Float: return typeof(float); case XmlTypeCode.Int: return typeof(int); case XmlTypeCode.NonPositiveInteger: case XmlTypeCode.NegativeInteger: case XmlTypeCode.Integer: case XmlTypeCode.Long: return typeof(long); case XmlTypeCode.Short: return typeof(short); case XmlTypeCode.Name: case XmlTypeCode.NCName: case XmlTypeCode.NmToken: case XmlTypeCode.Text: case XmlTypeCode.String: return typeof(string); case XmlTypeCode.UnsignedInt: return typeof(uint); case XmlTypeCode.NonNegativeInteger: case XmlTypeCode.PositiveInteger: case XmlTypeCode.UnsignedLong: return typeof(ulong); case XmlTypeCode.UnsignedShort: return typeof(ushort); default: return null; } } public override void ResetValue(object component) { } public override void SetValue(object component, object value) { switch (type) { case XmlTypeCode.Time: case XmlTypeCode.Date: case XmlTypeCode.DateTime: attr.Value = XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.RoundtripKind); break; // Konvertierung nötig, um das Dezimaltrennzeichen korrekt zu wandeln case XmlTypeCode.Decimal: attr.Value = XmlConvert.ToString((decimal)value); break; case XmlTypeCode.Double: attr.Value = XmlConvert.ToString((double)value); break; case XmlTypeCode.Float: attr.Value = XmlConvert.ToString((float)value); break; default: attr.Value = value.ToString(); break; } } public override bool ShouldSerializeValue(object component) { return false; } internal static bool Supports(XAttribute item) { return TypeCodeToType(item.GetSchemaInfo().SchemaType.TypeCode) != null; } } |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |