显示枚举描述而不是名称

6

我的数据绑定设置如下:

ItemsSource="{Binding Source={my:Enumeration {x:Type credit:OccupationCategory}}}"
                      DisplayMemberPath="Description"
                      SelectedValue="{Binding EmplType}"
                      SelectedValuePath="Value"/>

它确实运行得很好。由于较大软件设计的更改,我不能再拥有任何生成INotifyPropertyChanged事件的内容,因此该类型的数据绑定无法使用。相反,我手动设置selectedIndex并从代码中构建选项,例如:

ItemsSource="{Binding Source={StaticResource ResidenceOwnershipType}}"/>

参考文献

<UserControl.Resources>
    <ObjectDataProvider x:Key="ResidenceOwnershipType" MethodName="GetValues" ObjectType="{x:Type System:Enum}" >
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="credit:ResidenceOwnershipType" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</UserControl.Resources>

这在构建列表选项和链接所有数据方面是有效的,但是我无法使组合框显示枚举中的描述标记而不是实际文本。

我尝试过类似于这样的方法:

DisplayMemberPath="Description"

但那不正确。我该如何做到这一点?

编辑:

我的枚举:

[DataContract]
public enum ResidenceOwnershipType
{
    [Description("")]
    None = 0,
    [Description("Owns Home Outright")]
    OwnsHomeOutright = 1,
    [Description("Buying Home")]
    BuyingHome = 2,
    [Description("Renting/Leasing")] //Weird order here reflects RouteOne website
    RentingLeasing = 4,
    [Description("Living w/Relatives")]
    LivingWithRelatives = 3,
    [Description("Owns/Buying Mobile Home")]
    MobileHome = 5,
    [Description("Unknown")]
    Unknown = 6
}
2个回答

15
如果您保留这个ItemsSource,则必须定义一个自定义的ItemTemplate,因为DisplayMemberPath仅是一条无法检索到描述的路径。
至于模板应该长什么样子:您可以将一个TextBlock绑定到枚举值(当前的DataContext),并通过ValueConverter使用Binding.Converter进行转换。代码只需使用一些反射来检索Description(如GetTypeGetCustomAttributes等)。
另外,可选方案是编写一个自定义方法,直接返回一个可用的集合(并在ObjectDataProvider中使用),或者编写一个自定义的标记扩展以实现相同的功能。

如果我们讨论的是ComponentModel.DescriptionAttribute,则以下是示例方法:

public static class EnumUtility
{
    // Might want to return a named type, this is a lazy example (which does work though)
    public static object[] GetValuesAndDescriptions(Type enumType)
    {
        var values = Enum.GetValues(enumType).Cast<object>();
        var valuesAndDescriptions = from value in values
                                    select new
                                        {
                                            Value = value,
                                            Description = value.GetType()
                                                .GetMember(value.ToString())[0]
                                                .GetCustomAttributes(true)
                                                .OfType<DescriptionAttribute>()
                                                .First()
                                                .Description
                                        };
        return valuesAndDescriptions.ToArray();
    }
}
<ObjectDataProvider x:Key="Data" MethodName="GetValuesAndDescriptions"
                    ObjectType="local:EnumUtility">
    <ObjectDataProvider.MethodParameters>
        <x:TypeExtension TypeName="local:TestEnum" />
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ListBox ItemsSource="{Binding Source={StaticResource Data}}"
         DisplayMemberPath="Description"
         SelectedValuePath="Value"/>

ObjectDataProvider中没有获取那个信息的方法吗? - Nathan Tornquist
@NathanTornquist:只要你编写一个返回包含描述作为属性或仅返回描述字符串(如果这是你所需的全部内容)的对象的方法,那就不会太难。 - H.B.
@NathanTornquist:您也可以将其实现为[Markup Extension](http://msdn.microsoft.com/en-us/library/ee855815.aspx),并放弃`ObjectDataProvider`(自定义标记扩展是解决我在XAML问题中的大多数方案)。 - H.B.
@NathanTornquist:您从未指定描述是什么,它实际上是枚举值的属性吗? - H.B.
是的。我已经添加了实际枚举值。旧的数据绑定逻辑能够提取并显示这些描述。这样可以让你的界面看起来更加美观。 - Nathan Tornquist
显示剩余3条评论

2

这个答案是在H.B.的答案上为我的应用程序实现的一个补充:

检查是否添加了Description属性:

Description = (value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(true).OfType<DescriptionAttribute>().Count() > 0 ? 
                                                value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(true).OfType<DescriptionAttribute>().First().Description 
                                                : value)

同时设置以下属性以确保正确的ID被使用:SelectedValuePath="Value"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接