Combobox конвертер для перечислений - PullRequest
4 голосов
/ 27 октября 2011

У меня есть перечисление со значениями вроде

HomeRun, StolenBase, FirstBase и т. Д.

Я хочу отобразить эти значения в выпадающем списке, с пробелом, вставленным перед заглавными буквами, чтобы он отображался как «Home Run», «Stolen Base» и т. Д.

У меня уже есть код, который может выполнять форматирование для меня, и я добавил этот код в метод 'Convert' реализации IValueConverter.

Мой вопрос: где мне нужно использовать этот конвертер (в xaml), чтобы форматирование было не только в раскрывающемся списке, но и в отображаемом значении? Нужно ли также реализовать ConvertBack?

Мне хорошо известно, как настроить «описания» для перечисления и использовать популярный конвертер EnumToDescriptionConverter, но я бы предпочел держаться подальше от этого.

Ответы [ 5 ]

7 голосов
/ 27 октября 2011

Я не уверен, что есть лучший способ, но вы можете достичь того, что хотите, используя ItemTemplate

<ComboBox.ItemTemplate>
    <DataTemplate>
        <ContentPresenter
            Content="{Binding Converter={StaticResource baseballEnumConverter}}"/>
     </DataTemplate>
</ComboBox.ItemTemplate>

. Это отобразит преобразованное значение в вашем ComboBox.SelectedValue ComboBox по-прежнему будет значением Enum.Вам не нужно будет реализовывать ConvertBack.

2 голосов
/ 27 октября 2011

[обновлено] Ключевым моментом моего ответа является то, что значения перечисления полностью преобразуются. Я думаю, что этот способ проще, чем покрытие каждого значения перечисления. [/ updated]

Где мне нужно использовать этот конвертер (в xaml), чтобы не только выпадающий список, но и отображаемое значение Форматирование

В связующем элементе источника ComboBox (ItemsSource="{Binding Source={x:Null}, Converter={StaticResource converter}}"), пожалуйста, проверьте следующий код.

Нужно ли также реализовать ConvertBack?

Нет, вы этого не сделаете. , поскольку во время выполнения вы не можете изменять перечисление, и даже если это возможно, вы не можете изменить ItemsSource ComboBox в VIEW, что означает, что режим привязки - OneWay. 1022 *

1024 * XAML *

<Window x:Class="WpfApplication2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication2"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:MyEnumConverter x:Key="converter"/>
    </Window.Resources>
    <StackPanel>
        <ComboBox ItemsSource="{Binding Source={x:Null}, Converter={StaticResource converter}, Mode=OneWay}"></ComboBox>
    </StackPanel>
</Window>

код

public enum MyEnum
{
    HomeRun, StolenBase, FirstBase
}

[ValueConversion(typeof(object), typeof(List<string>))]
public class MyEnumConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var names = Enum.GetNames(typeof (MyEnum)).ToArray();
        //Add some code to support the thing you want to do(add blank in front of Capital...)
        return names;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
1 голос
/ 27 октября 2011

Если вы хотите, чтобы выбранное значение ComboBox было преобразовано обратно в перечисление, то вам нужно будет реализовать ConvertBack.

Я бы лично пошел с атрибутом descriptionшаблон, который вы упомянули, потому что

  1. очевидные вопросы уже заданы, и
  2. Вы не ограничены просто вставкой пробелов в верхнем регистре - вы можете использовать любое описание, которое хотите.

Но если вы хотите использовать этот шаблон, вам просто нужно правильно написать конвертер.Я бы предложил что-то вроде этого:

// Convert method
var formattedNames = new List<string>();
foreach (var value in Enum.GetValues(typeof(Things)))
{
    // Format is a method to convert the enum value to the display string
    var formattedName = Format(value);
    formattedNames.Add(formattedName);
}
// return a list of strings that you can bind to
return formattedNames;

// ConvertBack method
// Unformat is a method to revert the display string back to the enum value
var value = Unformat(formattedValue);
return Enum.Parse(typeof(Things), value);

Вы также можете создать простой класс для хранения как отображаемого значения, так и перечисления, а затем соответствующим образом установить свойство DisplayPath в поле со списком

class DisplayEnum
{
    public string DisplayValue { get;set; }
    public MyEnum ActualValue { get;set; }
}

<ComboBox DisplayMemberPath=DisplayValue ...

Редактировать

Я понимаю, что это не сработает, потому что ConvertBack пытается преобразовать строку в перечисление, но фактический набор привязок равен List<string>.Я оставлю это здесь, потому что это начало в правильном направлении.

Я думаю, вам понадобится два конвертера

  1. для преобразования enum введите в набор значений перечисления и
  2. для преобразования значения перечисления в строку.Этот второй конвертер должен реализовывать метод ConvertBack.

Как я уже указывал, если вы не реализуете ConvertBack , вы не сможете привязать SelectedValue обратно к вашему свойству enum в ViewModel.

0 голосов
/ 27 октября 2011

Есть подсказка, которую вы можете использовать для начала:

http://geekswithblogs.net/jawad/archive/2005/06/24/EnumDropDown.aspx

Я разработал своих собственных помощников по связыванию перечислений, начиная с этой идеи.

0 голосов
/ 27 октября 2011

Вам потребуется создать словарь или другую структуру поиска, которая отображает значение Enum в строковое представление.

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