我正在将一个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?的属性的类的实例。
在我的XAML文件中完成了Combo的SelectedValue绑定。
<ComboBox
Name="theCombo"
SelectedValue="{Binding Path=TheNullableProperty,
UpdateSourceTrigger=PropertyChanged}"/>
问题:
当绑定属性的值最初为非空时,组合框会正确显示该值。
但是,当绑定属性的值最初为空时,组合框为空白。
看起来数据绑定的各个方面都在工作,除了在首次显示组合框时表示空值。
例如:您可以从下拉列表中选择“可能”,并且绑定属性将正确设置为空。只是初始加载失败了。也许我需要手动设置SelectedValue...
我的解决方案
- Add a hidden textblock databound to the underlying nullable enum value via a Converter that converts from the nullable enum to a string (enum.ToString, or "null").
- Load up the combo box with 'ComboItems' each having a string Label (displayed in the combo) and a string Value equal to the enum values as strings (and "null" for the null value).
Data-bind the combo box to the textblock.
/// <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(); }