В качестве примера возьмем следующий код:
public enum ExampleEnum { FooBar, BarFoo }
public class ExampleClass : INotifyPropertyChanged
{
private ExampleEnum example;
public ExampleEnum ExampleProperty
{ get { return example; } { /* set and notify */; } }
}
Я хочу связать свойство ExampleProperty с ComboBox, чтобы оно отображало параметры «FooBar» и «BarFoo» и работало в режиме TwoWay. Оптимально, я хочу, чтобы мое определение ComboBox выглядело примерно так:
<ComboBox ItemsSource="What goes here?" SelectedItem="{Binding Path=ExampleProperty}" />
В настоящее время в моем окне установлены обработчики для событий ComboBox.SelectionChanged и ExampleClass.PropertyChanged, где я выполняю привязку вручную.
Есть ли лучший или какой-то канонический способ? Вы обычно используете конвертеры и как бы вы заполнили ComboBox правильными значениями? Я даже не хочу начинать с i18n прямо сейчас.
редактировать
Поэтому был дан ответ на один вопрос: как мне заполнить ComboBox правильными значениями.
Получить значения Enum в виде списка строк через ObjectDataProvider из статического метода Enum.GetValues:
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="ExampleEnumValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="ExampleEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Это я могу использовать в качестве ItemsSource для моего ComboBox:
<ComboBox ItemsSource="{Binding Source={StaticResource ExampleEnumValues}}"/>
Ответы:
Вы можете создать собственное расширение разметки.
Пример использования:
В верхней части вашего XAML:
а потом...
И реализация ...
источник
ItemsSource
параметре. Чтобы сохранить связь между представлением и моделью, мне нужно было бы создать копию перечисления в ViewModel и код ViewModel для преобразования между ними ... Что сделает решение не таким уж простым. Или есть способ предоставить сам тип из ViewModel?В viewmodel вы можете иметь:
В XAML
ItemSource
связываетMyEnumTypeValues
иSelectedItem
связываетSelectedMyEnumType
.источник
Я предпочитаю не использовать имя enum в пользовательском интерфейсе. Я предпочитаю использовать разные значения для user (
DisplayMemberPath
) и разные для значения (в данном случае enum) (SelectedValuePath
). Эти два значения могут быть упакованы вKeyValuePair
и сохранены в словаре.XAML
C #
РЕДАКТИРОВАТЬ: Совместимо с шаблоном MVVM.
источник
Enum.GetValues
, но это не решило бы часть отображаемых имен. В конце, и особенно, если реализован I18n, вам придется вручную что-то менять, если в любом случае меняется enum. Но перечисления не должны часто меняться, если вообще, не так ли? +1public Dictionary<ExampleEnum, string> ExampleEnumsWithCaptions { get; } = new Dictionary<ExampleEnum, string>() { {ExampleEnum.FooBar, "Foo Bar"}, {ExampleEnum.BarFoo, "Reversed Foo Bar"}, //{ExampleEnum.None, "Hidden in UI"}, };
Я не знаю, возможно ли это только в XAML, но попробуйте следующее:
Дайте вашему ComboBox имя, чтобы вы могли получить к нему доступ в следующем коде: "typesComboBox1"
Теперь попробуйте следующее
источник
На основании принятого, но теперь удаленного ответа, предоставленного ageektrapped я создал уменьшенную версию без некоторых более продвинутых функций. Весь код включен сюда, чтобы вы могли скопировать и вставить его, а не блокировать с помощью link-rot.
Я использую тот,
System.ComponentModel.DescriptionAttribute
который действительно предназначен для описания времени проектирования. Если вам не нравится использовать этот атрибут, вы можете создать свой собственный, но я думаю, что использование этого атрибута действительно делает свою работу. Если вы не используете атрибут, имя по умолчанию будет соответствовать названию значения перечисления в коде.Вот класс, используемый в качестве источника элементов:
Вы можете использовать его в XAML следующим образом:
источник
Используйте ObjectDataProvider:
а затем привязать к статическому ресурсу:
Найти это решение в этом блоге
источник
Converter
проблеме перечисления в строку.Мой любимый способ сделать это с помощью
ValueConverter
так, чтобы ItemsSource и SelectedValue связывались с одним и тем же свойством. Это не требует никаких дополнительных свойств, чтобы ваша ViewModel была красивой и чистой.И определение конвертера:
Этот конвертер будет работать с любым перечислением.
ValueDescription
это просто простой класс соValue
свойством иDescription
свойством. Вы также можете легко использоватьTuple
сItem1
и иItem2
илиKeyValuePair
сKey
иValue
вместо значения и описания или любой другой класс по вашему выбору, если он может содержать значение перечисления и строковое описание этого значения перечисления.источник
ValueDescription
классаDescription
свойство может быть опущено, если не нужно. Простой класс с единственнымValue
свойством также работает!.Select(e => e.ToString())
Вместо использованияValueDescription
класса.ValueDescription
чтобыKeyValuePair
можно было использовать, как показано здесьВот общее решение с использованием вспомогательного метода. Это также может обрабатывать перечисление любого базового типа (байт, sbyte, uint, long и т. Д.)
Вспомогательный метод:
Посмотреть модель:
Поле со списком:
источник
Вы можете рассмотреть что-то вроде этого:
Определите стиль для текстового блока или любого другого элемента управления, который вы хотите использовать для отображения вашего перечисления:
определите свой стиль для ComboBoxItem
добавьте комбинированный список и загрузите его с вашими значениями перечисления:
если ваше перечисление велико, вы, конечно, можете сделать то же самое в коде, не тратя много времени на ввод текста. Мне нравится такой подход, поскольку он упрощает локализацию - вы определяете все шаблоны один раз, а затем обновляете только файлы строковых ресурсов.
источник
Если вы используете MVVM, основываясь на ответе @rudigrobler, вы можете сделать следующее:
Добавьте следующее свойство в класс ViewModel
Затем в XAML сделайте следующее:
источник
Это
DevExpress
конкретный ответ, основанный на ответе сGregor S.
наибольшим количеством голосов (в настоящее время он имеет 128 голосов).Это означает, что мы можем поддерживать согласованность стилей во всем приложении:
К сожалению, оригинальный ответ не работает с
ComboBoxEdit
DevExpress без некоторых модификаций.Во-первых, XAML для
ComboBoxEdit
:Нет необходимости говорить, что вам нужно указать
xamlExtensions
на пространство имен, которое содержит класс расширения XAML (который определен ниже):И мы должны указать
myEnum
на пространство имен, которое содержит перечисление:Затем перечисление:
Проблема с XAML заключается в том, что мы не можем использовать
SelectedItemValue
, поскольку это приводит к ошибке, так как установщик недоступен (немного упущения с вашей стороны,DevExpress
). Таким образом, мы должны изменить нашViewModel
чтобы получить значение непосредственно из объекта:Для полноты вот расширение XAML из исходного ответа (слегка переименованное):
Отказ от ответственности: я не имею никакого отношения к DevExpress. Telerik также отличная библиотека.
источник
Попробуйте использовать
источник
Я создал проект CodePlex с открытым исходным кодом, который делает это. Вы можете скачать пакет NuGet здесь .
источник