0

这似乎并没有让我的组合框显示更友好的名称。我不确定我做错了什么。

<ComboBox ItemsSource="{Binding MyTypes, Mode=OneTime}"
          SelectedItem="{Binding SelectedType}"/>
public sealed class MyType : IMyInterface
{
    public override string ToString()
    {
        return "Friendlier Name";
    }
}

另外,我尝试使用IValueConverter(不起作用)...

<ComboBox ItemsSource="{Binding MyTypes, Mode=OneTime}"
          MemberDisplayPath="{Binding Converter={StaticResource MyConverter}}"
          SelectedItem="{Binding SelectedType}"/>
[ValueConversion(typeof(Type), typeof(String))]
public sealed class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var type = value as Type;

        if (type == null)
        {
            return DependencyProperty.UnsetValue;
        }

        return type.ToString();
    }

    ...
}

问题是 IValueConverter 似乎只能获取我的 ViewModel,因为它的值被传入......所以不确定那里发生了什么。

4

3 回答 3

2

使用 aDataTemplate并在那里应用您的转换器。

<ComboBox.ItemTemplate>
    <DataTemplate>
         <TextBlock Text="{Binding Converter={StaticResource MyConverter}}"/>
    </DataTemplate>
</ComboBox.ItemTemplate>
于 2012-05-14T15:24:51.947 回答
2

我为您修复IValueConverter了您的问题……只要您绑定到Type对象,您就需要创建一个实例并ToString()在该实例上使用覆盖。请记住,如果你的类对它们有一些疯狂的构造逻辑,这可能会变得混乱。

[ValueConversion(typeof(Type), typeof(String))]
internal sealed class TypeNameConverter : IValueConverter
{
    private static readonly IDictionary<Type, string> TypeNameCache = new Dictionary<Type, string>();
    private static readonly object TypeNameCacheLock = new Object();

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var type = value as Type;

        if (type == null)
        {
            return DependencyProperty.UnsetValue;
        }

        string result;

        lock (TypeNameCacheLock)
        {
            if (!TypeNameCache.TryGetValue(type, out result))
            {
                var instance = Activator.CreateInstance(type);

                result = instance.ToString();

                TypeNameCache.Add(type, result);
            }
        }

        return result;
    }

    ...
}

这部分是从 HB 的答案中复制的,它是工作所必需的:)

<ComboBox.ItemTemplate>
    <DataTemplate>
         <TextBlock Text="{Binding Converter={StaticResource MyConverter}}"/>
    </DataTemplate>
</ComboBox.ItemTemplate>
于 2012-05-14T15:45:39.023 回答
0

您正在使用的属性实际上被称为DisplayMemberPath,它的工作方式比您的代码建议的要简单得多。

像这样更改您的代码:

public sealed class MyType : IMyInterface
{
    public string FriendlyName
    {
        get { return "Friendlier Name"; }
    }
}

然后在您的 Xaml 集中DisplayMemberPath="FriendlyName",您就完成了。

(我建议把你的转换器扔掉。如果你要将整个类转换为字符串值,那么通常有一种更简单的方法。)

于 2012-05-14T15:26:55.707 回答