对类型的组合框进行数据绑定并覆盖其显示字符串

时间:2012-05-14 15:19:37

标签: c# wpf xaml data-binding combobox

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

<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,因为它的值被传入...所以不确定那里发生了什么。

3 个答案:

答案 0 :(得分:2)

使用DataTemplate并在那里应用转换器。

<ComboBox.ItemTemplate>
    <DataTemplate>
         <TextBlock Text="{Binding Converter={StaticResource MyConverter}}"/>
    </DataTemplate>
</ComboBox.ItemTemplate>

答案 1 :(得分: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;
    }

    ...
}

这一部分是从H.B.的答案中复制而来的,并且是工作所必需的:)

<ComboBox.ItemTemplate>
    <DataTemplate>
         <TextBlock Text="{Binding Converter={StaticResource MyConverter}}"/>
    </DataTemplate>
</ComboBox.ItemTemplate>

答案 2 :(得分:0)

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

更改您的代码:

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

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

(抛弃您的转换器,我建议。如果您将整个类转换为字符串值,那么通常会有一种更简单的方法。)