Laden...

[erledigt] PropertyGrid - Sortierung

Erstellt von Mighty Panther vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.798 Views
Mighty Panther Themenstarter:in
22 Beiträge seit 2008
vor 14 Jahren
[erledigt] PropertyGrid - Sortierung

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

D
500 Beiträge seit 2007
vor 14 Jahren

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

Mighty Panther Themenstarter:in
22 Beiträge seit 2008
vor 14 Jahren

@DaMoe80:

Danke für die schnelle Antwort.
Ich werde deinen Vorschlag mal probieren.

THX
Mighty

Mighty Panther Themenstarter:in
22 Beiträge seit 2008
vor 14 Jahren

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)));
}

D
500 Beiträge seit 2007
vor 14 Jahren

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

Mighty Panther Themenstarter:in
22 Beiträge seit 2008
vor 14 Jahren

@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)));
	}
}

D
500 Beiträge seit 2007
vor 14 Jahren

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

Mighty Panther Themenstarter:in
22 Beiträge seit 2008
vor 14 Jahren

@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!