Ich möchte mehrere Instanzen einer Klasse in meinem PropertyGrid
anzeigen. Die Klasse sieht wie folgt aus:PropertyGrid readonly Eigenschaft auf Objektebene
public class Parameter
{
[Description("the name")]
public string Name { get; set; }
[Description("the value"), ReadOnly(true)]
public string Value { get; set; }
[Description("the description")]
public string Description { get; set; }
}
ich viele Instanzen dieser Klasse in einem TreeView
haben. Wenn ich einen von ihnen in meinem TreeView
auswähle, werden die Eigenschaften wie erwartet im PropertyGrid
angezeigt. So weit so gut, aber ich möchte dieses Verhalten in der folgenden Weise anpassen:
Für jede einzelne Instanz möchte ich in der Lage sein zu verhindern, dass der Benutzer eine bestimmte Eigenschaft ändern kann. Durch Setzen von ReadOnly(true)
innerhalb meiner Klasse (wie Sie im obigen Beispiel sehen können), werden alle Value
Eigenschaften auf einer Klassenebene deaktiviert.
Nach einigen Recherchen fand ich die folgende Lösung, die mir die Möglichkeit gibt, eine bestimmte Eigenschaft zur Laufzeit aktivieren/deaktivieren:
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this)["Value"];
ReadOnlyAttribute attr =
(ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];
FieldInfo isReadOnly = attr.GetType().GetField(
"isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
isReadOnly.SetValue(attr, false);
Dieser Ansatz funktioniert nur gut, aber leider auch auf Klassenebene nur. Das bedeutet, wenn ich die Value
‚s isReadOnly
-false
, Set alle meiner Parameter
-Objekte haben die Value
Eigenschaft beschreibbar. Aber ich will das NUR für dieses eine Objekt (also Objekt-Ebene). Ich möchte wirklich keine separaten Klassen für Lese-/Schreib- und Lese-Eigenschaften erstellen.
Als ich aus Ideen leite, wird Ihre Hilfe sehr geschätzt :)
Vielen Dank im Voraus!
EDIT: Ich brauche die Readonly-Eigenschaften ausgegraut, so dass der Benutzer sehen kann, dass es nicht erlaubt oder möglich ist, sie zu bearbeiten.
Ich habe das gesamte Dokument gelesen, verstehe aber Ihre Idee immer noch nicht. Könnten Sie mir ein kleines Codebeispiel geben, um es etwas übersichtlicher zu gestalten? Vielen Dank für Ihre Zeit :) –
Siehe den Abschnitt * Dynamische Verwendung * in diesem Artikel. Kurz gesagt: Wenden Sie ein PropertyAttributesProviderAttribute auf Ihre Eigenschaft an, schreiben Sie Ihren eigenen Anbieter und ersetzen Sie die Attribute aus der PropertyAttributes-Auflistung basierend auf dem Objekt selbst (und nicht auf der Klasse). –
Wie ich im Quellcode sehen kann, erfordert dies, die benutzerdefinierte PropertyGrid-Implementierung des Autors zu verwenden, damit es funktioniert? In meinem Fall muss ich ein vorhandenes PropertyGrid verwenden, das sich in einer DLL befindet (die ich nicht ändern kann). –