WPF ComboBox双向绑定

时间:2010-11-22 16:51:13

标签: wpf binding

我有一个简单的ComboBox,它有一些简单的值。我正在尝试使用我的模型上的枚举属性进行双向绑定。

<ComboBox d:LayoutOverrides="Height" Grid.Column="1" SelectedItem="{Binding SortType, Converter={StaticResource sortSelect}, Mode=TwoWay}">
      <ListBoxItem Content="Ascending" Tag="Ascending"/>
      <ListBoxItem Content="Descending" Tag="Descending"/>
      <ListBoxItem Content="Absolute Ascending" Tag="AbsoluteAscending"/>
      <ListBoxItem Content="Absolute Descending" Tag="AbsoluteDescending" />
    </ComboBox>

这是我的ValueConverter

public class RdiSortMatchConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var val = (RdiSort) value;
        switch (val)
        {
            case RdiSort.Ascending:
                return "Ascending";
            case RdiSort.Descending:
                return "Descending";
            case RdiSort.AbsoluteAscending:
                return "Absolute Ascending";
            case RdiSort.AbsoluteDescending:
                return "Absolute Descending";
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (RdiSort) Enum.Parse(typeof (RdiSort), (string) ((ListBoxItem) value).Tag);
    }
}

ConvertBack方法工作正常,并根据Tag中的ListBoxItem值更新我的模型,但我无法获得初始Enum值以选择正确的ListBoxItem

了解实现这一目标的最佳方法,还是有更好的方法来约束Enums(考虑到我需要每个Enum值的自定义说明。

2 个答案:

答案 0 :(得分:2)

你可以这样做。首先为每个枚举值添加说明

public enum RdiSort
{ 
    [Description("Ascending Description")] 
    Ascending, 
    [Description("Descending Description")] 
    Descending, 
    [Description("AbsoluteAscending Description")] 
    AbsoluteAscending,
    [Description("AbsoluteDescending Description")] 
    AbsoluteDescending
} 

然后为您的ComboBox使用ObjectDataProvider

xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:MyEnumerations="clr-namespace:MyEnumerations" 

<ObjectDataProvider MethodName="GetValues" 
                    ObjectType="{x:Type sys:Enum}" 
                    x:Key="RdiSortValues"> 
    <ObjectDataProvider.MethodParameters> 
        <x:Type TypeName="MyEnumerations:RdiSort" /> 
    </ObjectDataProvider.MethodParameters> 
</ObjectDataProvider> 

在ComboBox中使用RdiSortValues提供程序,并使用TextBlock和Converter创建一个DataTemplate,以查看Description而不是Enum值。

<local:EnumDescriptionConverter x:Key="EnumDescriptionConverter"/>

<ComboBox SelectedItem="{Binding SortType}"
          ItemsSource="{Binding Source={StaticResource RdiSortValues}}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

最后是转换器。不需要ConvertBack,因为转换器仅在TextBlock中用于显示。

public class EnumDescriptionConverter : IValueConverter
{
    private string GetEnumDescription(Enum enumObj)
    {
        FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
        object[] attribArray = fieldInfo.GetCustomAttributes(false);
        if (attribArray.Length == 0)
        {
            return enumObj.ToString();
        }
        else
        {
            DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
            return attrib.Description;
        }
    }

    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            RdiSort myEnum = (RdiSort)value;
            string description = GetEnumDescription(myEnum);
            return description;
        }
        return null;
    }
    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return string.Empty;
    }
}

答案 1 :(得分:0)

这是我所做的解决方案。

.xaml =&gt;

<UserControl.Resources>
    <c:PriorityConvertor x:Key="priorityConvertor"></c:PriorityConvertor>
</UserControl.Resources>

.cs file =&gt;

public class PriorityConvertor : IValueConverter
{

    #region IValueConverter Members

    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
        {
            return string.Empty;
        }
        if (value.ToString() == "1")
        {
            return "High";
        }
        else if (value.ToString()  == "2")
        {
            return "Medium";
        }
        else if (value.ToString()  == "3")
        {
            return "Low";
        }
        return "Low";
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

}