WPF ComboBox 2-сторонняя привязка - PullRequest
1 голос
/ 22 ноября 2010

У меня есть простой ComboBox, который имеет несколько простых значений. Я пытаюсь выполнить двухстороннее связывание со свойством enum для моей модели.

<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

Каков наилучший способ достижения этого или есть лучший способ связывания t Enums (учтите, что мне нужны пользовательские описания для каждого значения Enum.

Ответы [ 2 ]

2 голосов
/ 23 ноября 2010

Вы можете сделать это так. Сначала добавьте описание для каждого из ваших значений Enum

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

Затем используйте ObjectDataProvider для вашего 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> 

Используйте поставщика RdiSortValues ​​в ComboBox и создайте шаблон данных с TextBlock и конвертером, чтобы увидеть описание вместо значения 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;
    }
}
0 голосов
/ 23 ноября 2010

Вот решение, которое я сделал.

.xaml =>

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

.cs file =>

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
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...