#c# #data-binding #combobox #listcontrol
#c# #привязка данных #combobox #listcontrol
Вопрос:
Предположим, у вас есть довольно небольшая последовательность элементов, где каждый элемент имеет свойства: Id и Name.
Id и Name уникальны.
Вы хотите отображать элементы в ListControl как поле со списком.
Вы хотите показать только имя элемента, а не идентификатор.
Когда выбрано имя отображаемого элемента, вы хотите, чтобы идентификатор элемента был выбран в качестве выбранного значения:
Это легко сделать с помощью источника данных, установив свойства DisplayMember и ValueMember
IList<Item> items = ...
this.ComboBox1.DataSource = items;
this.ComboBox1.DisplayMember = nameof(Item.Name);
this.ComboBox1.ValueMember = nameof(Item.Id)
Когда элемент выбран:
int selectedId = (int) this.ComboBox1.SelectedValue;
И вы можете выбрать элемент по идентификатору:
Item item = ...
this.ComboBox.SelectedValue = item.Id;
И вуаля, отображается имя элемента.
Но теперь у меня есть последовательность элементов без свойств, например, перечисление:
IList<MyEnum> enums = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().ToList();
this.comboBox1.DataSource = enums;
Этого достаточно, чтобы отобразить перечисления в поле со списком. Нет необходимости устанавливать DisplayMember / ValueMember.
Я могу получить выбранное перечисление:
MyEnum e = (MyEnum)this.ComboBox1.SelectedValue;
Но я не могу его установить:
MyEnum e = ...
this.ComboBox1.SelectedValue = e;
Приводит к исключению: System.Исключение InvalidOperationException: «Невозможно установить SelectedValue в ListControl с пустым значением ValueMember».
Итак, что я должен установить в ValueMember?
Комментарии:
1. Использовать
SelectedItem = e
2. Боже, неужели это так просто!
Ответ №1:
CharlieFace предложил следующее решение, и оно сработало:
private MyEnum SelectedEnum
{
get => (MyEnum)this.comboBox1.SelectedItem;
set => this.comboBox1.SelectedItem = value;
}
В моем примере со списком, который отображает идентификаторы элементов:
private Item SelectedItem
{
get => (Item)this.comboBox1.SelectedItem;
set => this.comboBox1.SelectedItem = value;
}
Таким образом, несмотря на то, что отображается только имя элемента; SelectedItem содержит полный элемент источника данных.
Спасибо, Чарли!