Erstellen / Ändern von Enums zur Laufzeit

8

Ich erstelle ein Programm, in dem der Benutzer seine eigenen benutzerdefinierten Eigenschaften erstellen kann, die letztendlich in einem PropertyGrid angezeigt werden. Im Moment möchte ich mich nicht mit benutzerdefinierten Editoren anlegen, also erlaube ich nur primitive Typeigenschaften ( string , int , double , DateTime , bool usw.), die PropertyGrid hat bereits eingebaute Editoren für.

Ich möchte dem Benutzer jedoch auch die Möglichkeit geben, Multiple-Choice-Eigenschaften zu erstellen, in denen er eine Liste möglicher Werte definieren kann, die wiederum als Drop-Down-Liste in PropertyGrid angezeigt werden.

Wenn ich ein Enum in meinem Code fest codiere, zeigt das Eigenschaftenraster automatisch Eigenschaften dieses enum als Dropdown-Liste an. Kann ich aber eine Enumeration zur Laufzeit erstellen und ändern, damit der Benutzer eine weitere Eigenschaftsoption hinzufügen kann, und zurück zu PropertyGrid gehen und ihre neue Option in einem Dropdown-Menü sehen?

Aktualisieren

Wenn wir Patricks Kommentar betrachten, denke ich, dass Enum s in diesem Fall nicht der richtige Weg sind. Also, wie kann ich stattdessen eine Liste von Strings verwenden, um ein Drop-Down in einem PropertyGrid Element zu füllen? Benötigte das einen benutzerdefinierten Editor?

    
Eric Anastas 14.04.2009, 02:31
quelle

4 Antworten

5

Die Antwort ist in einer einfachen Klasse: TypeConverter . (Und ja, Enums sind hier nicht geeignet).

Da ich nicht viele Details habe, gehe ich davon aus, dass Sie ein PropertyGrid über die SelectedObject-Eigenschaft mit einer Zielinstanz "verknüpft" haben und dass Ihre Zielinstanz ICustomTypeDescriptor implementiert, sodass Sie zur Laufzeit Eigenschaften (zB PropertyDescriptors) hinzufügen können . Ich kenne dein Design nicht, aber wenn du das nicht machst, rate ich dir, es dir anzuschauen.

Nehmen wir an, Sie fügen eine Zeichenfolgeneigenschaft hinzu und möchten, dass Ihr Benutzer eine Reihe von Einschränkungen für diese Eigenschaft angeben kann. Ihre Benutzerschnittstelle ermöglicht es dem Benutzer, eine Reihe von Zeichenfolgen einzugeben, und Sie erhalten als Ergebnis eine Liste von Zeichenfolgen. Vielleicht behalten Sie ein Wörterbuch mit Eigenschaften in Ihrer Zielinstanz, also nehmen wir an, dass diese neue Liste auch dort gespeichert wird.

Schreiben Sie jetzt einen neuen Konverter, der von TypeConverter abgeleitet ist (oder in diesem Beispiel vielleicht StringConverter). Sie müssen GetStandardValuesSupported überschreiben, um true zurückzugeben, und GetStandardValues ​​, um die Liste der Zeichenfolgen zurückzugeben (verwenden Sie den Parameter context, um auf die Instance-Eigenschaft und ihre String-Liste zuzugreifen). Dieser Konverter wird von Ihrem PropertyDescriptor mit der PropertyDescriptor.Converter-Eigenschaft veröffentlicht.

Ich hoffe, das ist nicht zu nebulös. Wenn Sie eine bestimmte Frage zu diesem Prozess haben, lassen Sie es mich wissen.

    
Nicolas Cadilhac 04.09.2009, 17:18
quelle
3

Die typische technische Lösung für Ihr Problem besteht darin, die Liste als Referenzdaten in Ihrer Datenbank zu pflegen. Im Allgemeinen werden Enums zur Kompilierzeit als Konstanten definiert, und ihre Änderung in späterem Code wird nicht empfohlen (geschweige denn Laufzeit), da dies zu Nebenwirkungen in Switch-Anweisungen führen kann.

    
Patrick 14.04.2009 02:52
quelle
0

Sie könnten Code mit Ihrem Code erstellen und ihn dann in einer temporären Textdatei speichern und dann verwenden. Dies wäre langsam, da es die Verwendung der Festplatte erfordert. Ich würde empfehlen, reflection zu betrachten.

Bearbeiten: Ich fand das perfekte Beispiel in einem meiner Bücher, hier ist es (es ist ziemlich lang, aber wenn Sie es in VS kopieren, wird es mehr Sinn ergeben).

%Vor%

Ausgabe: Summe von (2000) = 2001000
Schleifen. Verstrichene Millisekunden:
11468.75 für 1000000 Iterationen
Summe von (2000) = 2001000
Rohe Gewalt. Verstrichene Millisekunden:
406,25 für 1000000 Iterationen

Hier finden Sie einen Link zum gesamten Kapitel, wenn Sie weitere Informationen wünschen.

    
Kredns 14.04.2009 02:36
quelle
-7

Sie können Enum.GetNames () und Enum.GetValues ​​() verwenden, um Werte zu retrieven und dynamisch neue hinzuzufügen. obwohl ich dir vorschlage, eine Liste anstelle von enum zu verwenden oder dein Design zu überdenken. etwas riecht nicht richtig.

    
Srikar Doddi 14.04.2009 02:41
quelle

Tags und Links