In der Post Enum ToString wird eine Methode beschrieben, um das benutzerdefinierte Attribut DescriptionAttribute
wie folgt zu verwenden :
Enum HowNice {
[Description("Really Nice")]
ReallyNice,
[Description("Kinda Nice")]
SortOfNice,
[Description("Not Nice At All")]
NotNice
}
Und dann rufen Sie eine Funktion GetDescription
mit folgender Syntax auf:
GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"
Aber das hilft mir nicht wirklich, wenn ich eine ComboBox einfach mit den Werten einer Aufzählung füllen möchte, da ich die ComboBox nicht zum Aufrufen zwingen kannGetDescription
.
Was ich will, hat folgende Anforderungen:
- Beim Lesen
(HowNice)myComboBox.selectedItem
wird der ausgewählte Wert als Aufzählungswert zurückgegeben. - Der Benutzer sollte die benutzerfreundlichen Anzeigezeichenfolgen sehen und nicht nur den Namen der Aufzählungswerte. Anstatt "
NotNice
" zu sehen, würde der Benutzer "Not Nice At All
" sehen. - Hoffentlich erfordert die Lösung nur minimale Codeänderungen an vorhandenen Aufzählungen.
Natürlich könnte ich für jede von mir erstellte Aufzählung eine neue Klasse implementieren und diese überschreiben ToString()
, aber das ist eine Menge Arbeit für jede Aufzählung, und das möchte ich lieber vermeiden.
Irgendwelche Ideen?
Verdammt, ich werde mich sogar als Kopfgeld umarmen :-)
Antworten:
Sie können einen TypeConverter schreiben, der bestimmte Attribute liest, um sie in Ihren Ressourcen nachzuschlagen. Auf diese Weise erhalten Sie mehrsprachige Unterstützung für Anzeigenamen ohne großen Aufwand.
Sehen Sie sich die ConvertFrom / ConvertTo-Methoden von TypeConverter an und verwenden Sie Reflection, um Attribute in Ihren Enum- Feldern zu lesen .
quelle
ComboBox
hat alles, was Sie brauchen: dieFormattingEnabled
Eigenschaft, auf die Sie setzen solltentrue
, und dasFormat
Ereignis, in dem Sie die gewünschte Formatierungslogik platzieren müssen. So,quelle
DataGridComboBoxColumn
. Irgendeine Chance, es zu lösen? Ich bin nicht in der Lage, einen Weg zu finden, um Zugang zuComboBox
derDataGridComboBoxColumn
.Nicht! Aufzählungen sind Grundelemente und keine Benutzeroberflächenobjekte. Wenn sie der Benutzeroberfläche in .ToString () dienen, ist dies vom Entwurf her ziemlich schlecht. Sie versuchen hier das falsche Problem zu lösen: Das eigentliche Problem ist, dass Enum.ToString () nicht im Kombinationsfeld angezeigt werden soll!
Dies ist in der Tat ein sehr lösbares Problem! Sie erstellen ein UI-Objekt, um Ihre Kombinationsfeldelemente darzustellen:
Fügen Sie dann einfach Instanzen dieser Klasse zur Items-Auflistung Ihres Kombinationsfelds hinzu und legen Sie die folgenden Eigenschaften fest:
quelle
Dictionary
und die EigenschaftenKey
undValue
alsDisplayMember
und verwendet wurdenValueMember
.TypeConverter. Ich denke, das ist es, wonach ich gesucht habe. Alle begrüßen Simon Svensson !
Alles, was ich in meiner aktuellen Aufzählung ändern muss, ist, diese Zeile vor ihrer Deklaration hinzuzufügen.
Sobald ich das mache, wird jede Aufzählung mit den
DescriptionAttribute
Feldern angezeigt .Oh, und das
TypeConverter
würde so definiert werden:Dies hilft mir bei meinem ComboBox-Fall, überschreibt das aber offensichtlich nicht
ToString()
. Ich denke, ich werde mich in der Zwischenzeit damit zufrieden geben ...quelle
[TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}
, es versuchtConsole.WriteLine(MyEnum.One)
und es kommt immer noch als "Eins" heraus. Benötigen Sie spezielle Magie wieTypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One)
(die gut funktioniert)?Verwenden Sie Ihr Aufzählungsbeispiel:
Erstellen Sie eine Erweiterung:
Dann können Sie so etwas wie das Folgende verwenden:
Weitere Informationen finden Sie unter: http://www.blackwasp.co.uk/EnumDescription.aspx . Der Kredit geht an Richrd Carr für die Lösung
quelle
Sie können eine generische Struktur erstellen, die Sie für alle Ihre Aufzählungen mit Beschreibungen verwenden können. Bei impliziten Konvertierungen in und aus der Klasse funktionieren Ihre Variablen mit Ausnahme der ToString-Methode weiterhin wie die Aufzählung:
Anwendungsbeispiel:
quelle
Ich glaube nicht, dass Sie es schaffen können, ohne sich einfach an einen anderen Typ zu binden - zumindest nicht bequem. Selbst wenn Sie nicht steuern können
ToString()
, können SieTypeConverter
normalerweise eine benutzerdefinierte Formatierung verwenden - aber IIRCSystem.ComponentModel
berücksichtigt dies nicht für Aufzählungen.Sie könnten sich an eine
string[]
der Beschreibungen oder an etwas im Wesentlichen wie ein Schlüssel / Wert-Paar binden ? (Beschreibung / Wert) - so etwas wie:Und dann binden an
EnumWrapper<HowNice>.GetValues()
quelle
theComboBox.SelectItem
ist eine Art vonEnumWrapper<T>
, anstatt sichT
selbst. Ich denke, Scraimer willReading (HowNice)myComboBox.selectedItem will return the selected value as the enum value.
.Der beste Weg, dies zu tun, ist eine Klasse zu machen.
Ich glaube, das ist der beste Weg, dies zu tun.
In Comboboxen wird der hübsche ToString angezeigt, und die Tatsache, dass niemand mehr Instanzen Ihrer Klasse erstellen kann, macht sie im Wesentlichen zu einer Aufzählung.
ps Möglicherweise müssen einige geringfügige Syntaxkorrekturen vorgenommen werden. Ich bin nicht besonders gut mit C #. (Java-Typ)
quelle
private HowNice(String desc) : base(desc) { }
und die statischen Felder.Da Sie lieber nicht für jede Aufzählung eine Klasse erstellen möchten, würde ich empfehlen, ein Wörterbuch mit dem Aufzählungswert / Anzeigetext zu erstellen und diese stattdessen zu binden.
Beachten Sie, dass dies von den Methoden der GetDescription-Methode im ursprünglichen Beitrag abhängt.
quelle
Es ist nicht möglich, ToString () von Aufzählungen in C # zu überschreiben. Sie können jedoch Erweiterungsmethoden verwenden.
Natürlich müssen Sie die Methode explizit aufrufen, dh;
Dies ist keine schöne Lösung, mit einer switch-Anweisung und allem - aber es sollte funktionieren und hoffentlich ohne viele Umschreibungen ...
quelle
Nach der Antwort von @scraimer finden Sie hier eine Version des Konverters vom Typ Enum-to-String, der auch Flags unterstützt:
Und eine Erweiterungsmethode für die Verwendung:
quelle
Ich würde eine generische Klasse für jeden Typ schreiben. Ich habe in der Vergangenheit so etwas benutzt:
Darüber hinaus können Sie eine statische "Factory-Methode" hinzufügen, um eine Liste von Combobox-Elementen mit einem Aufzählungstyp zu erstellen (ziemlich genau wie die GetDescriptions-Methode, die Sie dort haben). Dies erspart Ihnen die Implementierung einer Entität pro Aufzählungstyp und bietet auch einen schönen / logischen Platz für die Hilfsmethode "GetDescriptions" (persönlich würde ich sie FromEnum (T obj) nennen ...
quelle
Erstellen Sie eine Sammlung, die das enthält, was Sie benötigen (z. B. einfache Objekte, die eine
Value
Eigenschaft mit demHowNice
Aufzählungswert und eineDescription
Eigenschaft mit enthaltenGetDescription<HowNice>(Value)
die Kombination mit dieser Sammlung und mit einer Datenbank verknüpft.Etwas wie folgt:
Wenn Sie eine Sammlungsklasse wie diese haben:
Wie Sie sehen können, kann diese Sammlung mit Lambdas leicht angepasst werden, um eine Teilmenge Ihres Enumerators auszuwählen und / oder eine benutzerdefinierte Formatierung zu implementieren,
string
anstatt die vonGetDescription<T>(x)
Ihnen erwähnte Funktion zu verwenden.quelle
Sie können PostSharp verwenden, um auf Enum.ToString abzuzielen und zusätzlichen Code hinzuzufügen. Dies erfordert keine Codeänderungen.
quelle
Sie müssen eine Aufzählung in eine ReadonlyCollection umwandeln und die Auflistung an die Combobox (oder ein beliebiges Steuerelement mit Schlüssel-Wert-Paar) binden.
Zunächst benötigen Sie eine Klasse, die die Elemente der Liste enthält. Da Sie lediglich das Int / String-Paar benötigen, empfehle ich die Verwendung einer Schnittstelle und einer Basisklassenkombination, damit Sie die Funktionalität in jedem gewünschten Objekt implementieren können:
Hier ist die Schnittstelle und eine Beispielklasse, die sie implementiert. Beachten Sie, dass der Schlüssel der Klasse stark in die Aufzählung eingegeben ist und dass die Eigenschaften von IValueDescritionItem explizit implementiert sind (sodass die Klasse alle Eigenschaften haben kann und Sie diejenigen auswählen können, die die implementieren Schlüssel / Wert-Paar.
Jetzt die EnumToReadOnlyCollection-Klasse:
Alles, was Sie in Ihrem Code benötigen, ist:
Denken Sie daran, dass Ihre Sammlung mit MyItem eingegeben wurde, sodass der Combobox-Wert einen Aufzählungswert zurückgeben sollte, wenn Sie an die entsprechende Eigenschaft binden.
Ich habe die Eigenschaft T this [Enum t] hinzugefügt, um die Sammlung noch nützlicher zu machen als ein einfaches Combo-Verbrauchsmaterial, zum Beispiel textBox1.Text = enumcol [HowNice.ReallyNice] .NicenessDescription;
Sie können MyItem natürlich in eine Schlüssel- / Wertklasse umwandeln, die nur für diese Puprose verwendet wird, und MyItem in den Typargumenten von EnumToReadnlyCollection insgesamt effektiv überspringen, aber dann wären Sie gezwungen, den Schlüssel mit int zu verwenden (was bedeutet, combobox1.SelectedValue zu erhalten) würde int zurückgeben und nicht den Aufzählungstyp). Sie umgehen das, wenn Sie eine KeyValueItem-Klasse erstellen, um MyItem zu ersetzen, und so weiter und so fort ...
quelle
Tut mir leid, dass ich diesen alten Thread erstellt habe.
Ich würde den folgenden Weg gehen, um die Aufzählung zu lokalisieren, da sie dem Benutzer aussagekräftige und lokalisierte Werte und nicht nur die Beschreibung über ein Dropdown-Listen-Textfeld in diesem Beispiel anzeigen kann.
Zuerst erstelle ich eine einfache Methode namens OwToStringByCulture, um lokalisierte Zeichenfolgen aus einer globalen Ressourcendatei abzurufen. In diesem Beispiel handelt es sich um BiBongNet.resx im Ordner App_GlobalResources. Stellen Sie in dieser Ressourcendatei sicher, dass alle Zeichenfolgen mit den Werten der Aufzählung übereinstimmen (ReallyNice, SortOfNice, NotNice). Bei dieser Methode übergebe ich den Parameter: resourceClassName, der normalerweise der Name der Ressourcendatei ist.
Als Nächstes erstelle ich eine statische Methode zum Füllen einer Dropdown-Liste mit enum als Datenquelle namens OwFillDataWithEnum. Diese Methode kann später mit jeder Aufzählung verwendet werden.
Dann habe ich auf der Seite mit einer Dropdown-Liste namens DropDownList1 in Page Load die folgende einfache Codezeile festgelegt, um die Aufzählung der Dropdown-Liste zu füllen.
Das ist es. Ich denke, mit einigen einfachen Methoden wie diesen können Sie jedes Listensteuerelement mit einer beliebigen Aufzählung füllen, nicht nur als beschreibende Werte, sondern als lokalisierten Text, der angezeigt werden soll. Sie können alle diese Methoden als Erweiterungsmethoden zur besseren Verwendung festlegen.
Ich hoffe das hilft. Teilen, um geteilt zu werden!
Hier sind die Methoden:
quelle
Um dies zu beheben, sollten Sie eine Erweiterungsmethode und ein Array von Zeichenfolgen wie folgt verwenden:
Einfacher Code und schnelle Dekodierung.
quelle
Ich habe diesen Ansatz ausprobiert und er hat bei mir funktioniert.
Ich habe eine Wrapper-Klasse für Enums erstellt und den impliziten Operator überladen, damit ich ihn Enum-Variablen zuweisen kann (in meinem Fall musste ich ein Objekt an einen
ComboBox
Wert binden ).Sie können Reflection verwenden, um die Aufzählungswerte so zu formatieren, wie Sie möchten. In meinem Fall
DisplayAttribute
rufe ich die Aufzählungswerte ab (falls vorhanden).Hoffe das hilft.
BEARBEITEN:
Nur für den Fall, ich benutze die folgende Funktion, um die
enum
Werte zu erhalten, die ich für dieDataSource
derComboBox
quelle
Sobald Sie die
GetDescription
Methode haben (sie muss global statisch sein), können Sie sie über eine Erweiterungsmethode verwenden:quelle
quelle
Sie können Enum als definieren
und dann verwenden
HowNice.GetStringValue()
.quelle