В посте Enum ToString описан метод для использования пользовательского атрибута, DescriptionAttribute
например:
Enum HowNice {
[Description("Really Nice")]
ReallyNice,
[Description("Kinda Nice")]
SortOfNice,
[Description("Not Nice At All")]
NotNice
}
А затем вы вызываете функцию GetDescription
, используя синтаксис, такой как:
GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"
Но это не очень помогает мне, когда я хочу просто заполнить ComboBox значениями перечисления, так как я не могу заставить ComboBox вызыватьGetDescription
.
То, что я хочу, имеет следующие требования:
- Чтение
(HowNice)myComboBox.selectedItem
вернет выбранное значение в качестве значения перечисления. - Пользователь должен видеть удобные для отображения строки, а не только имя значений перечисления. Таким образом, вместо того, чтобы видеть "
NotNice
", пользователь будет видеть "Not Nice At All
". - Надеемся, что решение потребует минимальных изменений кода в существующих перечислениях.
Очевидно, я мог бы реализовать новый класс для каждого создаваемого перечисления и переопределить его ToString()
, но для каждого перечисления это большая работа, и я бы предпочел этого избежать.
Любые идеи?
Черт, я даже бросить в объятия как Баунти :-)
Ответы:
Вы можете написать TypeConverter, который читает указанные атрибуты, чтобы искать их в ваших ресурсах. Таким образом, вы получите многоязычную поддержку отображаемых имен без особых хлопот.
Изучите методы ConvertFrom / ConvertTo TypeConverter и используйте отражение, чтобы прочитать атрибуты в ваших полях перечисления .
источник
ComboBox
имеет все, что вам нужно:FormattingEnabled
свойство, которое вы должны установитьtrue
, иFormat
событие, где вам нужно разместить желаемую логику форматирования. Таким образом,источник
DataGridComboBoxColumn
хотя. Есть ли шанс решить это? Я не могу найти способ , чтобы получить доступ кComboBox
изDataGridComboBoxColumn
.Не надо! Перечисления являются примитивами, а не объектами пользовательского интерфейса - заставить их обслуживать пользовательский интерфейс в .ToString () было бы довольно плохо с точки зрения дизайна. Вы пытаетесь решить не ту проблему здесь: реальная проблема заключается в том, что вы не хотите, чтобы Enum.ToString () отображался в поле со списком!
Теперь это действительно решаемая проблема! Вы создаете объект пользовательского интерфейса для представления элементов вашего поля со списком:
А затем просто добавьте экземпляры этого класса в коллекцию Items вашего поля со списком и установите эти свойства:
источник
Dictionary
и использовали свойстваKey
andValue
в качествеDisplayMember
иValueMember
.TypeConverter. Я думаю, что это то, что я искал. Приветствую Саймона Свенссона !
Все, что мне нужно изменить в моем текущем перечислении, это добавить эту строку перед их объявлением.
Как только я это сделаю, любое перечисление будет отображаться с использованием
DescriptionAttribute
его полей.Да, и это
TypeConverter
будет определено так:Это помогает мне в моем случае с ComboBox, но, очевидно, на самом деле не отменяет
ToString()
. Я полагаю, я согласен на это ...источник
[TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}
, попытался сделать,Console.WriteLine(MyEnum.One)
и это все еще выходит как "Один". Вам нужна особая магия вродеTypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One)
(которая работает нормально)?Используя ваш пример перечисления:
Создать расширение:
Тогда вы можете использовать что-то вроде следующего:
Смотрите: http://www.blackwasp.co.uk/EnumDescription.aspx для получения дополнительной информации. Кредит идет на Ричард Карр для решения
источник
Вы могли бы создать общую структуру, которую вы могли бы использовать для всех ваших перечислений, которые имеют описания. С неявными преобразованиями в и из класса ваши переменные по-прежнему работают как перечисление, за исключением метода ToString:
Пример использования:
источник
Я не думаю, что вы можете сделать это без простой привязки к другому типу - по крайней мере, не удобно. Обычно, даже если вы не можете контролировать
ToString()
, вы можете использоватьTypeConverter
пользовательское форматирование - но IIRCSystem.ComponentModel
не учитывает это для перечислений.Вы можете привязать к
string[]
описанию или что-то вроде пары ключ / значение? (описание / ценность) - что-то вроде:А затем привязать к
EnumWrapper<HowNice>.GetValues()
источник
theComboBox.SelectItem
это типEnumWrapper<T>
, а неT
сам по себе. Я думаю скреймер хочетReading (HowNice)myComboBox.selectedItem will return the selected value as the enum value.
.Лучший способ сделать это - создать класс.
Я считаю, что это лучший способ сделать это.
При заполнении в выпадающих списках будет показана симпатичная строка ToString, и тот факт, что никто не может создавать больше экземпляров вашего класса, по существу делает его перечислением.
PS, возможно, должны быть некоторые небольшие исправления синтаксиса, я не очень хорош с C #. (Java парень)
источник
private HowNice(String desc) : base(desc) { }
и статические поля.Учитывая, что вы не хотите создавать класс для каждого перечисления, я бы рекомендовал создать словарь значения перечисления / отображаемого текста и связать его вместо этого.
Обратите внимание, что это зависит от методов метода GetDescription в исходном посте.
источник
Невозможно переопределить ToString () перечислений в C #. Однако вы можете использовать методы расширения;
Конечно, вам придется сделать явный вызов метода, т.е.
Это не очень хорошее решение, с оператором switch и прочим - но оно должно работать и, надеюсь, без переписывания ...
источник
В продолжение ответа @scraimer, вот версия конвертера типов enum-to-string, который также поддерживает флаги:
И метод расширения для его использования:
источник
Я бы написал общий класс для использования с любым типом. Я использовал что-то подобное в прошлом:
Кроме того, вы можете добавить статический «фабричный метод», чтобы создать список элементов комбинированного списка с заданным типом перечисления (почти такой же, как у вашего метода GetDescription). Это избавит вас от необходимости реализовывать одну сущность для каждого типа перечисления, а также обеспечит удобное / логичное место для вспомогательного метода «GetDescription» (лично я бы назвал его FromEnum (T obj) ...
источник
Создайте коллекцию, которая содержит то, что вам нужно (например, простые объекты, содержащие
Value
свойство, содержащееHowNice
значение enum, иDescription
свойство, содержащееGetDescription<HowNice>(Value)
и привязывающее комбинацию данных к этой коллекции.Немного похоже на это:
когда у вас есть такой класс коллекции:
Как вы можете видеть, эту коллекцию легко настроить с помощью лямбды, чтобы выбрать подмножество вашего перечислителя и / или реализовать пользовательское форматирование
string
вместо использованияGetDescription<T>(x)
функции, которую вы упоминаете.источник
Вы можете использовать PostSharp для таргетинга Enum.ToString и добавить дополнительный код, который вы хотите. Это не требует каких-либо изменений кода.
источник
Вам нужно превратить перечисление в коллекцию ReadonlyCollection и привязать коллекцию к комбинированному списку (или любому другому элементу управления ключом-значением в этом отношении)
Прежде всего вам нужен класс, чтобы содержать элементы списка. Поскольку все, что вам нужно, это пара int / string, я предлагаю использовать интерфейс и комбо базового класса, чтобы вы могли реализовать функциональность в любом объекте, который вы хотите:
Вот интерфейс и пример класса, который его реализует. Обратите внимание, что ключ класса строго типизирован для Enum, и что свойства IValueDescritionItem реализованы явно (поэтому класс может иметь любые свойства, и вы можете выбрать те, которые реализуют Пара ключ / значение.
Теперь класс EnumToReadOnlyCollection:
Итак, все, что вам нужно в вашем коде:
Помните, что ваша коллекция набирается с помощью MyItem, поэтому значение в выпадающем списке должно возвращать значение перечисления, если вы привязываетесь к соответствующему объекту.
Я добавил свойство T this [Enum t], чтобы сделать коллекцию еще более полезной, чем простой комбинированный расходный материал, например textBox1.Text = enumcol [HowNice.ReallyNice] .NicenessDescription;
Конечно, вы можете выбрать превращение MyItem в класс Key / Value, используемый только для этой куколки, фактически пропуская MyItem в аргументах типа EnumToReadnlyCollection, но тогда вам придется использовать для ключа int (что означает получение combobox1.SelectedValue). вернул бы int, а не тип enum). Вы можете обойти это, если создадите класс KeyValueItem для замены MyItem и так далее, и так далее ...
источник
Извините за получение этой старой темы.
Я бы пошел следующим образом, чтобы локализовать enum, так как он может отображать значимые и локализованные значения для пользователя, а не только описание, через текстовое поле раскрывающегося списка в этом примере.
Сначала я создаю простой метод с именем OwToStringByCulture для получения локализованных строк из файла глобальных ресурсов, в данном примере это BiBongNet.resx в папке App_GlobalResources. Внутри этого файла ресурсов убедитесь, что все строки совпадают со значениями перечисления (ReallyNice, SortOfNice, NotNice). В этом методе я передаю параметр: resourceClassName, который обычно является именем файла ресурса.
Затем я создаю статический метод для заполнения выпадающего списка enum в качестве источника данных, который называется OwFillDataWithEnum. Этот метод может быть использован с любым перечислением позже.
Затем на странице с раскрывающимся списком DropDownList1 я установил в Page_Load следующую простую строку кода, чтобы заполнить перечисление в раскрывающемся списке.
Вот и все. Я думаю, что с помощью некоторых простых методов, подобных этим, вы можете заполнить любой элемент управления списком любым перечислением, причем не только в качестве описательных значений, но и для отображения локализованного текста. Вы можете сделать все эти методы как методы расширения для лучшего использования.
Надеюсь, это поможет. Поделитесь, чтобы поделиться!
Вот методы:
источник
Чтобы решить эту проблему, вы должны использовать метод расширения и массив строк следующим образом:
Простой код и быстрое декодирование.
источник
Я попробовал этот подход, и он работал для меня.
Я создал класс-обертку для перечислений и перегрузил неявный оператор, чтобы я мог назначить его переменным перечисления (в моем случае мне пришлось привязать объект к
ComboBox
значению).Вы можете использовать отражение для форматирования значений перечисления так, как вы хотите, в моем случае я извлекаю
DisplayAttribute
значения перечисления вне (если они есть).Надеюсь это поможет.
РЕДАКТИРОВАТЬ:
На всяком случае, я использую следующую функцию , чтобы получить
enum
значение , которые я использую дляDataSource
изComboBox
источник
Когда у вас есть
GetDescription
метод (он должен быть глобальным статическим), вы можете использовать его через метод расширения:источник
источник
Вы можете определить Enum как
а затем использовать
HowNice.GetStringValue()
.источник