我将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设置为一个类的实例,该类具有MyEnum类型的名为TheNullableProperty(对于此示例)的属性。
Combo的SelectedValue的绑定在我的XAML文件中完成。
<ComboBox
Name="theCombo"
SelectedValue="{Binding Path=TheNullableProperty,
UpdateSourceTrigger=PropertyChanged}"/>
问题:
当bound属性的值最初为非null时,组合框会正确显示该值。
但是当bound属性的值最初为null时,组合框为空。
当首次显示组合框时,看起来数据绑定的每个方面都与空值的表示不同。
例如:您可以从下拉列表中选择Maybe,并将bound属性正确设置为null。只是初始加载失败了。也许我只需要手动设置SelectedValue ......
将组合框数据绑定到文本块。
/// <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();
}
答案 0 :(得分:5)
您无法在WPF(至少3.5 SP1)中按设计绑定到空值。这意味着,当Source获取Null作为值时,您的Binding将自动被破坏,即使您为Source指定了有效值也无法工作。您需要通过Value Converter为您的绑定提供一些“心脏跳动”机制。因此,Converter将null值转换为Targets的某些“Undefined”(非null),并且能够将“Undefined”转换回null ...
答案 1 :(得分:2)
将 null 作为ComboBox
或ListBox
的有效值似乎存在许多问题,因为类似的问题已被提出here,{ {3}}和here。
对于其中任何一个都没有一个极好的,食人魔的回答。
我自己的建议是将Maybe
添加为MyEnum
的成员。我知道这只是一个例子但如果MyEnum
的所有内容都可以为空,那么MyEnum
可能应该有一个Undefined
成员(或者类似的东西),这对于enums来说很常见
答案 2 :(得分:1)
我在网上找到了这个解决方案,我觉得这个解决方案非常好。我并不完全理解它的实现 - 它是一些非常严肃的.NET功夫 - 但从我作为用户的角度来看它很棒。试一试:
http://philondotnet.wordpress.com/2009/09/18/how-to-select-null-none-in-a-combobox-listbox-listview/
答案 3 :(得分:1)
DependencyProperty.UnsetValue Field
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace MyConverters
{
[ValueConversion(typeof(DateTime), typeof(String))]
public class StringToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int number;
return int.TryParse(value.ToString(), out number) ? number : DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.ToString();
}
}
}
答案 4 :(得分:0)
这是解决此问题的一个非常简单的解决方案:
不要在ItemsSource中使用值为null的项目,而是使用DbNull.Value作为项目或项目的value属性。
我在这里详细描述了这种方法:https://stackoverflow.com/a/44170898/6713814