2010-11-22 6 views
1

J'ai un simple ComboBox qui a quelques valeurs simples. J'essaie de faire une liaison bidirectionnelle avec une propriété enum sur mon modèle.WPF ComboBox Liaison bidirectionnelle

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

Voici mon 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); 
    } 
} 

La méthode ConvertBack fonctionne très bien, et met à jour mon modèle basé sur la valeur Tag dans le ListBoxItem, mais je ne peux pas obtenir la valeur Enum initiale pour sélectionner la ListBoxItem correcte

quelle est la meilleure façon d'y parvenir, ou existe-t-il un meilleur moyen de lier t Enums (prendre en compte que j'ai besoin d Descriptions pour chaque valeur Enum.

+0

Voir cette question: [Databinding une propriété ENUM à un ComboBox dans WPF] (http://stackoverflow.com/questions/58743/databinding-an-enum-property-to-a-combobox-in-wpf) –

Répondre

2

Vous pouvez le faire comme ceci. Tout d'abord ajouter une description pour chacun de vos Enum valeurs

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

Ensuite, utilisez un ObjectDataProvider pour votre ComboBox

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> 

Utilisez le fournisseur de RdiSortValues ​​dans votre zone de liste déroulante et créer un DataTemplate avec un TextBlock et un convertisseur pour voir la description au lieu de la valeur 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> 

Et enfin le convertisseur. Il n'y a pas besoin de ConvertBack puisque le convertisseur est seulement utilisé dans le TextBlock pour l'affichage.

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

Voici la solution que j'ai faite.

.xaml =>

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

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

}