【问题标题】:Show Enum Description Instead of Name显示枚举描述而不是名称
【发布时间】:2012-07-11 19:23:29
【问题描述】:

我有这样的数据绑定设置:

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
}

【问题讨论】:

    标签: c# wpf xaml data-binding enums


    【解决方案1】:

    如果您保留此ItemsSource,则必须定义一个自定义ItemTemplate,因为DisplayMemberPath 只是您无法检索描述的路径。

    至于模板应该是什么样子:您可以将TextBlock 绑定到枚举值(当前DataContext)并使用Binding.Converter 将其通过ValueConverter 进行管道传输。该代码只是检索DescriptionGetTypeGetCustomAttributes 等)的一些反射

    Alternatives 是一种自定义方法,可以立即返回可用的集合(并在 ObjectDataProvider 中使用)或自定义 markup extension,它执行相同的操作。


    如果我们谈论的是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 获取这些信息?
    • @NathanTornquist:只有当您编写一个返回包含描述作为属性的对象的方法,或者仅将描述作为字符串(如果这就是您所需要的)时,才不会太难。
    • @NathanTornquist:您也可以将其实现为 Markup Extension 并放弃 ObjectDataProvider(自定义标记扩展是我的大多数 XAML 问题的解决方案)。
    • 从阅读到它,看起来编写自定义方法将是最好的解决方案。然后我可以用 GetValuesAndDescription 或类似的东西替换 GetValues。我真的不知道如何。你是否足够精通这一点,你可以提供一个例子吗?
    • @NathanTornquist:您从未指定描述是什么,它实际上是枚举值的属性吗?
    【解决方案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"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 2022-10-03
      • 2019-06-20
      • 2021-10-07
      • 2021-04-17
      • 1970-01-01
      • 2022-11-01
      相关资源
      最近更新 更多