W poście Enum ToString metoda jest opisana w celu użycia atrybutu niestandardowego w DescriptionAttribute
następujący sposób:
Enum HowNice {
[Description("Really Nice")]
ReallyNice,
[Description("Kinda Nice")]
SortOfNice,
[Description("Not Nice At All")]
NotNice
}
Następnie wywołujesz funkcję GetDescription
, używając składni takiej jak:
GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"
Ale to nie pomaga mi, gdy chcę po prostu wypełnić ComboBox wartościami wyliczenia, ponieważ nie mogę zmusić ComboBox do wywołaniaGetDescription
.
To, czego chcę, ma następujące wymagania:
- Odczyt
(HowNice)myComboBox.selectedItem
zwróci wybraną wartość jako wartość wyliczenia. - Użytkownik powinien widzieć przyjazne dla użytkownika łańcuchy wyświetlania, a nie tylko nazwy wartości wyliczenia. Zamiast więc zobaczyć „
NotNice
”, użytkownik zobaczy „Not Nice At All
”. - Miejmy nadzieję, że rozwiązanie będzie wymagało minimalnych zmian kodu w istniejących wyliczeniach.
Oczywiście mógłbym zaimplementować nową klasę dla każdego wyliczenia, które utworzę, i zastąpić jej ToString()
, ale to dużo pracy dla każdego wyliczenia i wolałbym tego uniknąć.
Jakieś pomysły?
Cholera, nawet przytulę jako nagrodę :-)
Odpowiedzi:
Możesz napisać TypeConverter, który odczytuje określone atrybuty, aby wyszukać je w zasobach. W ten sposób bez większego kłopotu uzyskasz obsługę wielu języków dla wyświetlanych nazw.
Zapoznaj się z metodami ConvertFrom / ConvertTo TypeConverter i użyj odbicia, aby odczytać atrybuty w polach wyliczenia .
źródło
ComboBox
ma wszystko, czego potrzebujesz:FormattingEnabled
właściwość, którą powinieneś ustawićtrue
, iFormat
zdarzenie, w którym musisz umieścić żądaną logikę formatowania. A zatem,źródło
DataGridComboBoxColumn
chociaż. Jakaś szansa na rozwiązanie tego problemu? Nie mogę znaleźć sposobu na uzyskanie dostępu doComboBox
domenyDataGridComboBoxColumn
.Nie! Wyliczenia są prymitywami, a nie obiektami UI - uczynienie ich obsługi UI w .ToString () byłoby bardzo złe z punktu widzenia projektowania. Próbujesz tutaj rozwiązać niewłaściwy problem: prawdziwy problem polega na tym, że nie chcesz, aby Enum.ToString () pojawiało się w polu kombi!
Teraz jest to rzeczywiście bardzo możliwy do rozwiązania problem! Tworzysz obiekt UI reprezentujący elementy z pola kombi:
Następnie po prostu dodaj wystąpienia tej klasy do kolekcji Items pola kombi i ustaw następujące właściwości:
źródło
Dictionary
i używali właściwościKey
iValue
jakoDisplayMember
iValueMember
.TypeConverter. Myślę, że właśnie tego szukałem. Witajcie, Simon Svensson !
Wszystko, co muszę zmienić w moim bieżącym wyliczeniu, to dodać tę linię przed ich deklaracją.
Gdy to zrobię, każde wyliczenie zostanie wyświetlone przy użyciu
DescriptionAttribute
jego pól.Aha, i
TypeConverter
byłoby to zdefiniowane w ten sposób:Pomaga mi to w przypadku mojej skrzynki ComboBox, ale oczywiście w rzeczywistości nie zastępuje
ToString()
. W międzyczasie zgodzę się na to ...źródło
[TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}
, próbowałemConsole.WriteLine(MyEnum.One)
i nadal wychodzi jako „Jeden”. Czy potrzebujesz jakiejś specjalnej magiiTypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One)
(która działa dobrze)?Na podstawie przykładu wyliczenia:
Utwórz rozszerzenie:
Następnie możesz użyć czegoś takiego jak:
Więcej informacji można znaleźć pod adresem : http://www.blackwasp.co.uk/EnumDescription.aspx . Rozwiązanie należy do Richrda Carra
źródło
Możesz stworzyć ogólną strukturę, której możesz użyć dla wszystkich swoich wyliczeń, które mają opisy. Dzięki niejawnym konwersjom do iz klasy zmienne nadal działają jak wyliczenie, z wyjątkiem metody ToString:
Przykład użycia:
źródło
Myślę, że nie da się tego zrobić bez prostego wiązania się z innym typem - przynajmniej nie jest to wygodne. Normalnie, nawet jeśli nie możesz kontrolować
ToString()
, możesz użyć a,TypeConverter
aby wykonać niestandardowe formatowanie - ale IIRCSystem.ComponentModel
nie uwzględnia tego w przypadku wyliczeń.Możesz powiązać się z jednym
string[]
z opisów lub czymś zasadniczo podobnym do pary klucz / wartość? (opis / wartość) - coś takiego:A następnie powiąż z
EnumWrapper<HowNice>.GetValues()
źródło
theComboBox.SelectItem
jest typemEnumWrapper<T>
zamiastT
siebie. Myślę, że Scraimer chceReading (HowNice)myComboBox.selectedItem will return the selected value as the enum value.
.Najlepszym sposobem na to jest utworzenie klasy.
Uważam, że to najlepszy sposób na zrobienie tego.
Po umieszczeniu w comboboxach ładny ToString zostanie pokazany, a fakt, że nikt nie może utworzyć więcej instancji twojej klasy, zasadniczo sprawia, że jest to wyliczenie.
ps może zaistnieć potrzeba drobnych poprawek składni, nie jestem zbyt dobry z C #. (Facet Java)
źródło
private HowNice(String desc) : base(desc) { }
i pól statycznych.Biorąc pod uwagę, że wolisz nie tworzyć klasy dla każdego wyliczenia, polecam utworzenie słownika wartości wyliczenia / wyświetlanego tekstu i powiązanie go.
Zauważ, że ma to zależność od metod metody GetDescription w oryginalnym poście.
źródło
Nie można zastąpić ToString () wyliczeń w języku C #. Możesz jednak użyć metod rozszerzających;
Oczywiście będziesz musiał wykonać jawne wywołanie metody, tj;
To nie jest miłe rozwiązanie, z instrukcją przełącznika i wszystkim - ale powinno działać i, miejmy nadzieję, bez wielu przeróbek ...
źródło
Idąc za odpowiedzią @scraimer, oto wersja konwertera typu wyliczenie na ciąg, który również obsługuje flagi:
I metoda rozszerzenia do korzystania z niego:
źródło
Napisałbym klasę ogólną do użytku z dowolnym typem. W przeszłości użyłem czegoś takiego:
Oprócz tego możesz dodać statyczną „metodę fabryczną”, aby utworzyć listę elementów combobox z podanym typem wyliczenia (prawie tak samo jak metoda GetDescriptions, którą tam masz). Oszczędziłoby to konieczności implementowania jednej encji dla każdego typu wyliczenia, a także zapewniło ładne / logiczne miejsce dla metody pomocniczej „GetDescriptions” (osobiście nazwałbym to FromEnum (T obj) ...
źródło
Utwórz kolekcję zawierającą to, czego potrzebujesz (na przykład proste obiekty zawierające
Value
właściwość zawierającąHowNice
wartość wyliczenia orazDescription
właściwość zawierającąGetDescription<HowNice>(Value)
i powiązaną z danymi kombi do tej kolekcji.Trochę tak:
kiedy masz taką klasę kolekcji:
Jak widać, tę kolekcję można łatwo dostosować za pomocą lambda, aby wybrać podzbiór
string
modułu wyliczającego i / lub zaimplementować niestandardowe formatowanie zamiast używać wspomnianejGetDescription<T>(x)
funkcji.źródło
Możesz użyć PostSharp do kierowania Enum.ToString i dodania dodatkowego kodu, który chcesz. Nie wymaga to żadnych zmian w kodzie.
źródło
To, czego potrzebujesz, to przekształcić wyliczenie w ReadonlyCollection i powiązać kolekcję z combobox (lub dowolną formantem z włączoną parą klucz-wartość)
Po pierwsze, potrzebujesz klasy, która będzie zawierała pozycje z listy. Ponieważ wszystko, czego potrzebujesz, to para int / string, sugeruję użycie interfejsu i kombinacji klasy bazowej, abyś mógł zaimplementować funkcjonalność w dowolnym obiekcie:
Oto interfejs i przykładowa klasa, która go implementuje. Zauważ, że klasa Key jest silnie wpisana do Enum i że właściwości IValueDescritionItem są jawnie zaimplementowane (więc klasa może mieć dowolne właściwości i możesz WYBRAĆ te, które implementują Para klucz / wartość.
Teraz klasa EnumToReadOnlyCollection:
Wszystko, czego potrzebujesz w swoim kodzie, to:
Pamiętaj, że Twoja kolekcja jest wpisywana za pomocą MyItem, więc wartość combobox powinna zwracać wartość wyliczenia, jeśli powiążesz się z odpowiednią właściwością.
Dodałem właściwość T this [Enum t], aby kolekcja była jeszcze bardziej użyteczna niż zwykłe materiały eksploatacyjne combo, na przykład textBox1.Text = enumcol [HowNice.ReallyNice] .NicenessDescription;
Możesz oczywiście zdecydować się zmienić MyItem w klasę Key / Value używaną tylko do tego puprose, skutecznie pomijając MyItem w argumentach typu EnumToReadnlyCollection, ale wtedy będziesz zmuszony przejść z int dla klucza (co oznacza uzyskanie combobox1. zwróci int, a nie typ wyliczenia). Możesz obejść ten problem, jeśli utworzysz klasę KeyValueItem, aby zastąpić MyItem i tak dalej, i tak dalej ...
źródło
Przepraszamy, że włączyłem ten stary wątek.
Poszedłbym w następujący sposób, aby zlokalizować wyliczenie, ponieważ może wyświetlać znaczące i zlokalizowane wartości dla użytkownika, a nie tylko opis, za pośrednictwem pola tekstowego listy rozwijanej w tym przykładzie.
Najpierw tworzę prostą metodę o nazwie OwToStringByCulture, aby pobrać zlokalizowane ciągi znaków z pliku zasobów globalnych, w tym przykładzie jest to BiBongNet.resx w folderze App_GlobalResources. W tym pliku zasobów upewnij się, że wszystkie ciągi są takie same, jak wartości wyliczenia (ReallyNice, SortOfNice, NotNice). W tej metodzie przekazuję parametr: resourceClassName, który jest zwykle nazwą pliku zasobów.
Następnie tworzę statyczną metodę wypełniania listy rozwijanej wyliczeniem jako źródłem danych o nazwie OwFillDataWithEnum. Tej metody można później użyć z dowolnym wyliczeniem.
Następnie na stronie z listą rozwijaną o nazwie DropDownList1 ustawiłem w Page_Load następujący tylko jeden prosty wiersz kodu, aby wypełnić wyliczenie na liście rozwijanej.
Otóż to. Myślę, że za pomocą kilku prostych metod, takich jak te, można wypełnić dowolną kontrolkę listy dowolnym wyliczeniem, nie tylko wartościami opisowymi, ale zlokalizowanym tekstem do wyświetlenia. Możesz uczynić wszystkie te metody jako metody rozszerzające w celu lepszego wykorzystania.
Mam nadzieję, że to pomoże. Udostępnij, aby się podzielić!
Oto metody:
źródło
Aby rozwiązać ten problem, powinieneś użyć metody rozszerzenia i tablicy ciągów, takich jak:
Prosty kod i szybkie dekodowanie.
źródło
Wypróbowałem to podejście i zadziałało.
Utworzyłem klasę opakowującą dla wyliczeń i przeładowałem niejawny operator, aby móc przypisać go do zmiennych wyliczeniowych (w moim przypadku musiałem powiązać obiekt z
ComboBox
wartością).Możesz użyć odbicia, aby sformatować wartości wyliczenia w sposób, w jaki chcesz, w moim przypadku pobieram
DisplayAttribute
wartości wyjściowe z wartości wyliczeniowych (jeśli istnieją).Mam nadzieję że to pomoże.
EDYTOWAĆ:
Tylko w przypadku, używam następujących funkcji w celu uzyskania
enum
wartości, które używam dlaDataSource
zComboBox
źródło
Gdy już masz
GetDescription
metodę (musi być globalna statyczna), możesz użyć jej za pomocą metody rozszerzającej:źródło
źródło
Możesz zdefiniować Enum jako
a następnie użyj
HowNice.GetStringValue()
.źródło