代码之家  ›  专栏  ›  技术社区  ›  Dean Chalk

WPF组合框双向绑定

  •  1
  • Dean Chalk  · 技术社区  · 14 年前

    我有一个简单的 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 值以选择正确的 列表框项

    实现这一目标的最佳方法是什么,或者是否有更好的绑定方法 Enums (考虑到我需要每个 枚举 价值。

    2 回复  |  直到 14 年前
        1
  •  2
  •   Fredrik Hedblad    14 年前

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

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

    然后对组合框使用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> 
    

    使用组合框中的RdiSortValues提供程序并创建一个带有文本块和转换器的数据模板,以查看描述而不是枚举值。

    <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>
    

    最后是转换器。不需要转换回,因为转换程序只在文本块中用于显示。

    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;
        }
    }
    
        2
  •  0
  •   rajiv chaudhary    14 年前

    这是我所做的解决办法。

    .xaml=>

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

    .cs文件=>

    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
    }
    

    }