Я пытаюсь найти простой пример, где перечисления отображаются как есть. Все примеры, которые я видел, пытаются добавить красивые строки отображения, но я не хочу такой сложности.
По сути, у меня есть класс, который содержит все свойства, которые я связываю, сначала установив DataContext для этого класса, а затем указав привязку, подобную этой, в файле xaml:
<ComboBox ItemsSource="{Binding Path=EffectStyle}"/>
Но это не показывает значения перечисления в ComboBox
элементах as.
Ответы:
Вы можете сделать это из кода, поместив следующий код в
Loaded
обработчик событий Window , например:Если вам нужно связать его в XAML, вам нужно использовать его
ObjectDataProvider
для создания объекта, доступного в качестве источника привязки:Обратите внимание на следующий код:
Руководство по отображению пространства имен и сборки вы можете прочитать на MSDN .
источник
xmlns:DllAlias="clr-namespace:NamespaceInsideDll; assembly=DllAssemblyName"
в XAML, чтобы использовать его. Вот руководство: msdn.microsoft.com/en-us/library/ms747086.aspxМне нравится, чтобы все объекты, которые я связываю, были определены в моем
ViewModel
, поэтому я стараюсь по возможности избегать использования<ObjectDataProvider>
в xaml.Мое решение не использует никаких данных, определенных в представлении, и никакого кода. Только DataBinding, повторно используемый ValueConverter, метод для получения коллекции описаний для любого типа Enum и единственное свойство в ViewModel для привязки.
Когда я хочу , чтобы привязать
Enum
кComboBox
тексту , который я хочу , чтобы отобразить никогда не соответствует значениямEnum
, поэтому я использую[Description()]
атрибут , чтобы дать ему текст , который я на самом деле хочу видеть вComboBox
. Если бы у меня был список дней недели, это выглядело бы примерно так:Сначала я создал вспомогательный класс с парой методов для работы с перечислениями. Один метод получает описание для определенного значения, другой метод получает все значения и их описания для типа.
Далее мы создаем
ValueConverter
. Наследование отMarkupExtension
упрощает использование в XAML, поэтому нам не нужно объявлять его как ресурс.Мои
ViewModel
потребности только 1 свойство , что мояView
может связываться как дляSelectedValue
иItemsSource
из выпадающего списка:И, наконец, связать
ComboBox
вид (используяValueConverter
вItemsSource
привязке) ...Для реализации этого решения вам нужно всего лишь скопировать мой
EnumHelper
класс иEnumToCollectionConverter
класс. Они будут работать с любыми перечислениями. Кроме того, я не включил его здесь, ноValueDescription
класс - это просто простой класс с двумя открытыми свойствами объекта, один вызванValue
, другой вызванDescription
. Вы можете создать это самостоятельно или изменить код для использованияTuple<object, object>
илиKeyValuePair<object, object>
источник
ValueDescription
класс , который имеет общие свойства дляValue
иDescription
Tuple<T1, T2>
или илиKeyValuePair<TKey, TValue>
вместоValueDescription
класса, и тогда вам не придется создавать свой собственный.Я использовал другое решение, используя MarkupExtension.
Я сделал класс, который обеспечивает элементы источника:
Это почти все ... Теперь используйте его в XAML:
Замените enum: States на свой enum
источник
e.ToString()
для отображения имени. Вы можете использовать свой собственный переводчик, анализатор атрибутов descrtiption, что угодно.{Binding Path=WhereEverYouWant}
), и если вы хотите, чтобы оно поддерживало двустороннее связывание, у вас также будет поле для поддержки. Таким образом, вы не заменяете 2 свойства и 1 вспомогательное поле, а только 1 однострочное свойство только для чтения.Используйте ObjectDataProvider:
а затем привязать к статическому ресурсу:
на основании этой статьи
источник
xmlns:System="clr-namespace:System;assembly=mscorlib"
Ответ Ника действительно помог мне, но я понял, что его можно немного подправить, чтобы избежать дополнительного класса ValueDescription. Я вспомнил, что в рамках фреймворка уже существует класс KeyValuePair, поэтому его можно использовать вместо этого.
Код меняется незначительно:
и, наконец, XAML:
Я надеюсь, что это полезно для других.
источник
KeyValuePair
но в конце я решил использовать aKeyValuePair
для представления чего-то, что не является парой ключ-значение, просто чтобы избежать написания тривиально простого класса, не имело смысла. ВValueDescription
классе всего 5 строчек, а 2 из них просто{
и}
Вам нужно будет создать массив значений в перечислении, который можно создать, вызвав System.Enum.GetValues () , передав ему
Type
перечисление, для которого вы хотите элементы.Если вы укажете это для
ItemsSource
свойства, то оно должно быть заполнено всеми значениями перечисления. Вы, вероятно, хотите связатьSelectedItem
сEffectStyle
(предполагая, что это свойство того же перечисления и содержит текущее значение).источник
Все вышеперечисленные посты пропустили простой трюк. Из привязки SelectedValue можно узнать, как АВТОМАТИЧЕСКИ заполнять ItemsSource, чтобы ваша разметка XAML была справедливой.
Например, в моей ViewModel у меня есть
ValidateRaiseAndSetIfChanged - моя ловушка INPC. Ваш может отличаться.
Реализация EnumComboBox заключается в следующем, но сначала мне понадобится небольшой помощник, чтобы получить строки и значения перечисления
и основной класс (обратите внимание, я использую ReactiveUI для перехвата изменений свойств через WhenAny)
Вам также нужно правильно установить стиль в Generic.XAML, иначе ваша коробка ничего не будет рендерить, и вы выдернете свои волосы.
и это все. Это, очевидно, может быть расширено для поддержки i18n, но сделает этот пост длиннее.
источник
Универсальные приложения работают немного по-другому; он не обладает всей мощью полнофункционального XAML. Что сработало для меня:
Просто для забавы я собрал небольшой шаблонный класс, чтобы помочь с этим, и опубликовал его на страницах примеров MSDN . Дополнительные биты позволяют мне при желании переопределить имена перечислений и позволяют скрывать некоторые перечисления. Мой код ужасно похож на код Ника (выше), который я хотел бы видеть раньше.
источник
На этот вопрос есть много отличных ответов, и я смиренно отвечаю на свой. Я считаю, что мое несколько проще и элегантнее. Требуется только конвертер значений.
Учитывая перечисление ...
и преобразователь значения ...
Ресурсы...
Декларация XAML ...
Посмотреть модель ...
Результирующий комбобокс ...
источник
Вы должны расширить ответ Роджерса и Грега с помощью такого рода конвертера значений Enum, если вы привязываетесь напрямую к свойствам объектной модели enum.
источник
Если вы привязываете к фактическому свойству enum в вашей ViewModel, а не к int представлению enum, все становится сложно. Я обнаружил, что необходимо привязать к строковому представлению, а не к значению int, как ожидается во всех приведенных выше примерах.
Вы можете определить, так ли это, связав простое текстовое поле со свойством, с которым вы хотите связать вашу ViewModel. Если он показывает текст, привязать к строке. Если он показывает число, привязать к значению. Заметьте, я использовал Display дважды, что обычно было бы ошибкой, но это единственный способ, которым он работает.
Greg
источник
Мне понравился ответ tom.maruska , но мне нужно было поддерживать любой тип enum, с которым мой шаблон может столкнуться во время выполнения. Для этого мне пришлось использовать привязку, чтобы указать тип расширения разметки. Я смог поработать в этом ответе от nicolay.anykienko, чтобы придумать очень гибкое расширение разметки, которое сработало бы в любом случае, о котором я могу подумать. Это потребляется так:
Источник расширения с разметкой, на который делаются пометки, упомянутый выше:
источник
Простое и понятное объяснение: http://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/
...
...
источник
С помощью
ReactiveUI
, я создал следующее альтернативное решение. Это не элегантное решение «все в одном», но, по крайней мере, оно легко читаемо.В моем случае привязка списка
enum
к элементу управления является редким случаем, поэтому мне не нужно масштабировать решение по базе кода. Однако код можно сделать более общим, изменив егоEffectStyleLookup.Item
наObject
. Я проверил это с моим кодом, никаких других изменений не требуется. Это означает, что один вспомогательный класс может быть применен к любомуenum
списку. Хотя это уменьшит его читабельность -ReactiveList<EnumLookupHelper>
не имеет большого смысла к этому.Используя следующий вспомогательный класс:
В ViewModel преобразуйте список перечислений и выставьте его как свойство:
В
ComboBox
, используйтеSelectedValuePath
свойство, чтобы привязать к исходномуenum
значению:В представлении это позволяет нам привязать оригинал
enum
кSelectedEffectStyle
в ViewModel, но отобразитьToString()
значение вComboBox
:источник
Я добавляю свой комментарий (к сожалению, в VB, но концепция может быть легко воспроизведена в C # в одно мгновение), потому что мне просто нужно было сослаться на это, и мне не понравились какие-либо ответы, поскольку они были слишком сложными. Это не должно быть так сложно.
Так что я придумал более простой способ. Привязать перечислители к словарю. Свяжите этот словарь с Combobox.
Мой комбобокс:
Мой код позади. Надеюсь, это поможет кому-то еще.
источник
Решение Ника можно упростить еще больше, без излишеств, вам понадобится только один конвертер:
Затем вы используете это там, где вы хотите, чтобы ваше поле со списком появилось:
источник
Я бы не рекомендовал реализовывать это как есть, но, надеюсь, это может вдохновить на хорошее решение.
Допустим, ваше перечисление Foo. Тогда вы можете сделать что-то вроде этого.
Затем в
Window.Load
методе вы можете загрузить все перечисления,ObservableCollection<FooViewModel>
которые вы можете установить в качестве DataContext комбинированного списка.источник
Я просто держал это простым. Я создал список элементов со значениями перечисления в моей ViewModel:
В моем коде xaml мне просто нужно это:
источник