Hallo!
Ich habe mich durch ca. 363 Themen zum Thema PropertyGrid gearbeitet, aber keine Lösung zu meinem Problem gefunden. (Zugegeben, den größten Teil habe ich nur überflogen.)
Zu meinem Problem...
Ich habe eine Klasse mit verschieden Eigenschaften.
Wenn ich ein Array mit nur einem Objekt dieser Klasse an ein PropertyGrid übergebe, dann Sortiert er mir die Eigenschaften, nach dem DisplayName-Attribute.
Wenn das Array aus mehren Objekten dieser Klasse besteht, dann sortiert mir das PropertyGrid die Eigenschaften nach dem Namen des Eigenschaftsfeldes.
Wie kann ich ermöglichen, dass er immer nach dem DisplayNamen sortiert?
Siehe Anhang
private void button1_Click(object sender, EventArgs e)
{
propertyGrid1.SelectedObjects = FillPG(1);
}
private void button2_Click(object sender, EventArgs e)
{
propertyGrid1.SelectedObjects = FillPG(3);
}
private object[] FillPG(int count)
{
ArrayList objects = new ArrayList();
for (int i = 0; i < count; i++)
{
ClassForPG myObject = new ClassForPG();
myObject.MyPropertyU = "Was ganz anderes";
myObject.MyPropertyX = "Irgendwas";
myObject.MyPropertyY = "Noch irgendwas";
objects.Add(myObject);
}
return objects.ToArray();
}
THX & LG
Mighty
Hallo Mighty,
ich habe nur eine Vermutung, weil ich vor einiger Zeit auch ein Sortierproblem hatte. Ich meine, dass das PropertyGrid intern mit einer PropertyDescriptorCollection arbeitet, die die zu visualisierenden Properties enthaelt. Ist diese Liste nicht richtig sortiert, dann wir das standard Sortierverhalten verwendet. Aus welchem Grund auch immer muss eine existierende Instanz der PropertyDescriptorCollection ueber die Sort-Methode mittels eines Arrays, welches die zu sortierenden Properties in bereits sortierter Reihenfolge enthaelt, sortiert werden also:
string[] sortedNames = new string[5];
sortedNames[0] = "b";
sortedNames[1] = "x";
sortedNames[2] = "d";
PropertyDescriptorCollection collection = new PropertyDescriptorCollection(...);
collection.Sort(sortedNames);
Die Descriptoren Liste habe ich dann aus der Methode
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] originalAttributes)
ueber einen TypeConverter zuruckgegeben.
Gruss, DaMoe
@DaMoe80:
Danke für die schnelle Antwort.
Ich werde deinen Vorschlag mal probieren.
THX
Mighty
Ich habe es versucht, aber das Endergebnis war das gleiche wie oben. 🙁
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
PropertyDescriptorCollection baseProps = base.GetProperties(attributes);
// alle DisplayName ermitteln
ArrayList arrDisplayName = new ArrayList();
foreach (PropertyDescriptor oProp in baseProps)
{
arrDisplayName.Add(oProp.DisplayName);
}
// DisplayName sortieren
arrDisplayName.Sort();
// Rückgabe nach sortierten DisplayName
return baseProps.Sort((string[])arrDisplayName.ToArray(typeof(string)));
}
Moin!
Wird der TypeDescriptor richtig angesprochen? Hast Du mal geschaut, ob die Liste richtig sortiert ist? Von welchem TypeDescriptor hast Du abgeleitet? Das PropertyGrid ist da sehr empfindlich. Deshalb leite bitte von **ExpandableObjectConverter **ab und dann ueberschreibe die Methode.
Sollte das nicht funktionieren, wuerde ich in das .NET Framework debuggen. Ich habe das Verhalten des Grid ebenfalls so beobachtet (natuerlich auch den Reflector zur Hilfe genommen).
Gruss, DaMoe
@DaMoe80:
Nochmals Danke, dass du dich meinem Problem annimmst.
Ich komme leider einfach nicht weiter. 🙁
Also, der TypeDescriptor spreche ich wie folgt an...
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public sealed class ClassForPG
{
[DisplayName("Eigenschaft A")]
public string MyPropertyX { get; set; }
[DisplayName("Eigenschaft B")]
public string MyPropertyY { get; set; }
[DisplayName("Eigenschaft C")]
public string MyPropertyU { get; set; }
}
public sealed class MyTypeDescriptionProvider : TypeDescriptionProvider
{
public MyTypeDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(ClassForPG)))
{ }
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new MyTypeDescriptor(base.GetTypeDescriptor(objectType, instance));
}
}
public sealed class MyTypeDescriptor : CustomTypeDescriptor
{
public MyTypeDescriptor(ICustomTypeDescriptor parent)
: base(parent)
{
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
PropertyDescriptorCollection baseProps = base.GetProperties(attributes);
// alle DisplayName ermitteln
ArrayList arrDisplayName = new ArrayList();
foreach (PropertyDescriptor oProp in baseProps)
{
arrDisplayName.Add(oProp.DisplayName);
}
// DisplayName sortieren
arrDisplayName.Sort();
// Rückgabe nach sortierten DisplayName
return baseProps.Sort((string[])arrDisplayName.ToArray(typeof(string)));
}
}
Hallo!
Zum einen versuche bitte, wie in meinem vorherigen Post angemerkt, einmal den ExpandableObjectConverter als Basisklasse zu verwenden. Du verwendest momentan noch den CustomTypeConverter.
Weiterhin solltest Du beachten, dass Deine Klasse wie folgt attributisiert werden muss:
[TypeConverter(typeof(MyTypeDescriptor))]
Gruss, DaMoe
@DaMoe80:
Hab es jetzt so geändert, wie du es gesagt hast und es funktioniert.
Das einzige was ich noch beachten musste, war die interne Eigenschaft der Sortierung des PropertyGrid noch zu ändern.
Also PG.PropertySort von CategorizedAlphabetical auf Categorized.
Also nochmals, Danke für deine Hilfe!