ComboBox типов с ValueConverter и пользовательскими атрибутами


Я использую MVVM, если это имеет значение.

Мой MainWindowViewModel имеет две зависимости: TheList и TheSelectedItem. TheList - это список, TheSelectedItem является типом .

Главное окно имеетComboBox . КогдаMainWindowViewModel загружается, он захватывает список всех классов в сборке, которые реализуютIMyInterface и устанавливаетTheList к этому.

Каждый из этих классов имеет пользовательский атрибут, называемый DisplayName, который имеет один параметр, который будет использоваться для отображения удобного имени для класса вместо имени, известного приложению для класса.

У меня также есть ValueConverter для прямой цели преобразования этих типов в отображаемые имена.

    public class TypeToDisplayName : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType.Name == "IEnumerable")
            {
                List<string> returnList = new List<string>();
                if (value is List<Type>)
                {
                    foreach (Type t in value as List<Type>)
                    {
                        returnList.Add(ReflectionHelper.GetDisplayName(t));
                    }
                }

                return returnList;
            }
            else
            {
                throw new NotSupportedException();
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return typeof(BasicTemplate);
        }
    }

Итак, то, что я получаю,- это ComboBox со списком имен, которые пользователь должен иметь возможность понимать. Потрясающе! Это именно то, чего я хочу!

Следующий шаг: я связываю свойство SelectedItem моегоComboBox с моимtheselecteditem свойством в моей ViewModel.

Вот в чем проблема: когда я делаю выбор, я получаю маленькую красную рамку вокруг моего ComboBox и свойство TheSelectedItem на моей ViewModel никогда не устанавливается.

Я почти уверен, что это из-за несоответствия типов (элементы в ComboBox теперь кажутся строками, и TheSelectedItem имеет тип Тип - также, когда я изменяю TheSelectedItem на строку вместо типа, это работает). Но я не знаю, где мне нужно начать кодирование, чтобы преобразовать (надеюсь, уникальное) DisplayName, которое находится в ComboBox, обратно в объект типа.

Заранее спасибо за любую помощь. На этот раз я в тупике.

2 3

2 ответа:

Если я правильно понял ваш вопрос, то вы используете этот конвертер на ItemsSource для ComboBox? В этом случае я думаю, что вы можете позволить ItemsSource быть таким, как он есть, и вместо этого просто преобразовать каждый тип, когда они представлены таким образом.

<ComboBox ...>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=typeName, Converter={StaticResource TypeToDisplayNameConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

А затем просто преобразуйте каждый тип в конвертере.

public class TypeToDisplayNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Type t = (Type)value;
        return ReflectionHelper.GetDisplayName(t);
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }
}

Убедитесь, что вы IsSynchronizedWithCurrentItem true на ComboBox. Проверьте это ...