Я связываю WPF ComboBox со значением типа MyEnum? (где MyEnum является перечисляемым типом)
Я программно заполняю элементы ComboBox следующим образом:
// The enum type being bound to
enum MyEnum { Yes, No }
// Helper class for representing combobox listitems
// (a combination of display string and value)
class ComboItem {
public string Display {get;set}
public MyEnum? Value {get;set}
}
private void LoadComboBoxItems()
{
// Make a list of items to load into the combo
var items = new List<ComboItem> {
new ComboItem {Value = null, Display = "Maybe"},
new ComboItem {Value = MyEnum.Yes, Display = "Yes"},
new ComboItem {Value = MyEnum.No, Display = "No"},};
// Bind the combo's items to this list.
theCombo.ItemsSource = items;
theCombo.DisplayMemberPath = "Display";
theCombo.SelectedValuePath = "Value";
}
Также в коде позади я устанавливаю DataContext для экземпляра класса со свойством TheNullableProperty (для этого примера в любом случае) типа MyEnum?.
Привязка SelectedValue для Combo выполняется в моем файле XAML.
<ComboBox
Name="theCombo"
SelectedValue="{Binding Path=TheNullableProperty,
UpdateSourceTrigger=PropertyChanged}"/>
Проблема:
Если значение свойства привязки изначально не равно нулю, поле со списком отображает значение правильно.
Но когда значение привязанного свойства изначально равно нулю, поле со списком остается пустым.
Похоже, что каждый аспект привязки данных работает отдельно от представления нулевого значения при первом показе комбинированного списка.
Например: вы можете выбрать Возможно из выпадающего списка, и свойство привязки будет правильно установлено на ноль. Это просто первоначальная загрузка, которая не удалась. Может быть, мне нужно просто вручную установить SelectedValue ...
Что я закончил делать
- Добавьте скрытую границу данных текстового блока к базовому значению перечисляемого значения, допускающего обнуляемое значение, с помощью преобразователя, который преобразует перечисляемое в значение обнуляемого перечисления в строку (enum.ToString или "null").
- Загрузите поле со списком 'ComboItems', каждое из которых имеет строку Label (отображается в комбинированном списке) и строку Value, равную значениям перечисления в виде строк (и "null" для значения NULL).
Привязка данных со списком к текстовому блоку.
/// <summary>
/// Convert from EnumeratedType? to string (null->"null", enum values->ToString)
/// </summary>
public class EnumConverter<T> : IValueConverter where T:struct
{
public static string To(T? c)
{
if (c == null)
return "null";
return c.ToString();
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return To((T?)value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var s = (string) value;
if (s == "null")
return null;
return (T?)Enum.Parse(typeof(T), s);
}
}
public class MyEnumConverter : EnumConverter<MyEnum>
{
}
public class ComboItem
{
public string Value { get; set; }
public string Label { get; set; }
public ComboItem(MyEnum? e, string label)
{
Value = MyEnumConverter.To(e);
Label = label;
}
}
static IEnumerable<ComboItem> GetItems()
{
yield return new ComboItem(null, "maybe");
yield return new ComboItem(MyEnum.Yes, "yup");
yield return new ComboItem(MyEnum.No, "nope");
}
private void SetupComboBox()
{
thecombo.ItemsSource = GetItems().ToList();
}