2010-11-22 147 views
1

我有一個簡單的ComboBox,它有一些簡單的值。我試圖用我的模型上的枚舉屬性做2路綁定。WPF 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方法工作正常,並基於ListBoxItemTag值我的模型更新,但我不能獲得初始Enum值來選擇正確的ListBoxItem

什麼是實現此目標的最佳方式,或者是否有更好的綁定方法?Enums(考慮到我需要自定義d爲每個Enum賦值。

+0

見這樣的問題:[在WPF數據綁定一個枚舉屬性組合框] (http://stackoverflow.com/questions/58743/databinding-an-enum-property-to-a-combobox-in-wpf) – 2010-11-22 17:04:33

回答

2

你可以這樣做。首先添加描述爲每個枚舉值

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提供商,並創建一個TextBlock和一個轉換器一個DataTemplate看說明而不是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> 

最後是轉換器。由於轉換器僅用於TextBlock中顯示,因此不需要ConvertBack。

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; 
    } 
} 
0

這是我所做的解決方案。

的.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 
} 

}