Быстрое решение
Создайте исходный класс для ваших ComboItems с (как минимум) свойствами для отображения и внутренним значением свойства.Если вы создаете универсальный класс, вы можете использовать его для всех ваших полей со списком.
class ComboDisplay<TSource>
{
public string Display {get; set;}
public TSource Value {get; set;}
}
cmbRoom.DisplayMember = nameof(ComboDisplay.Display);
cmbRoom.ValueMember = nameof(ComboDisplay.Value);
Когда вы создаете источник данных для вашего комбинированного списка, обязательно добавьте значение по умолчанию.В приведенном ниже примере я предполагаю, что вы хотите выбрать элементы типа Room
в вашем комбо:
IEnumerable<Room> availableRooms = myDbContext.Rooms
.Where(room => room.IsAvailable)
.Select(room => new ComboDisplay<Room>
{
Display = room.Name,
Value = new Room
{
Id = room.Id,
...
},
})
// add a dummy value if nothing is selected
.Concat(new Room[]
{
Display = "Please select a room",
Value = null, // meaning: nothing selected
});
После выбора используйте comboBox1.SelectedValue
, чтобы получить выбранную комнату, или ноль, если ничего не выбрано.
Создание специального класса Combobox
Если вам нужно использовать это регулярно, рассмотрите возможность создания общего подкласса ComboBox, который может отображать элементы определенного TSource и будет возвращать ноль, если ничего не выбрано:
class MyComboBox<TSource> : ComboBox
{
public MyComboBox() : base()
{
base.DataSource = this.EmptyList;
base.DisplayMember = nameof(ComboDisplay.Display);
base.ValueMember = nameof(ComboDisplay.Value);
}
private static readonly EmptyItem = new ComboDisplay
{
Display = "Please select a value",
Value = null,
}
Создайте свойство, которое возвращает доступные комбинированные элементы.Убедитесь, что EmptyItem всегда находится в коллекции:
public IReadonlyCollection<TSource> ComboItems
{
get {return (IReadOnlyCollection<TSource>)base.DataSource;}
set
{
// TODO: check if the empty element is in your list; if not add it
base.DataSource = value;
}
}
Наконец: функция для получения значения Selected или null, если ничего не выбрано:
public TSource SelectedValue
{
get => return (TSource)base.SelectedValue;
set
{
// TODO: check if value is in ComboItems
base.SelectedValue = value;
}
}