匿名类的DisplayNameAttribute

10

如果我有一个非匿名类,就像这样,我知道可以像这样使用DisplayNameAttribute

class Record{

    [DisplayName("The Foo")]
    public string Foo {get; set;}

    [DisplayName("The Bar")]
    public string Bar {get; set;}

}

但是我有

var records = (from item in someCollection
               select{
                   Foo = item.SomeField,
                   Bar = item.SomeOtherField,
               }).ToList();

我使用 records 作为 DataSource 在 DataGrid 中展示数据。列标题显示为 FooBar,但它们必须是 The FooThe Bar。由于一些内部原因,我不能创建一个具体的类,只能使用匿名类。在这种情况下,有没有办法为这个匿名类的成员设置 DisplayNameAttrubute

我尝试过:

[DisplayName("The Foo")] Foo = item.SomeField

但它不会编译。

谢谢。


我因为这个原因避免使用匿名类,而是创建了一个轻量级的数据对象。在你的情况下,它将是你已经发布的Record类。这里是否有使用匿名类的技术需求? - jglouie
2
我无法为一些不同的内部原因创建一个具体类。没有理由不能创建新类。你是不是磁盘空间不足了? - BFree
1
这并不是要表现出无礼,但如果我所在的组织内部有人说我不能创建一个类,我会开始准备我的简历。 - vcsjones
其中一个主要原因是我有大约70个类似这样的查询,我不想为每个查询创建一个类,只是为了使用DisplayNameAttribute。另一个原因是计划使用Dynamic Linq,以便在运行时让用户选择列。 - TheOtherGuy
@vcsjones 一个示例场景是Windows资源管理器。它默认显示关键列(详细视图),但用户可以选择包括其他列,如“作者”,“创建日期”等。 - TheOtherGuy
显示剩余2条评论
2个回答

3
据我所知,您无法将属性应用于匿名类型。编译器根本不支持它。您可以走得更远,使用类似Mono.Cecil的东西作为后期构建步骤,将属性放在那里,但这几乎不是您想考虑的事情。为什么一定要是匿名的呢?

感谢您的回答。我已在问题评论部分列出了我更喜欢匿名类的主要原因。 - TheOtherGuy

2
以下解决方案如何:

如下所示的解决方案:

dataGrid.SetValue(
    DataGridUtilities.ColumnHeadersProperty,
    new Dictionary<string, string> {
        { "Foo", "The Foo" },
        { "Bar", "The Bar" },
    });

dataGrid.ItemsSource = (from item in someCollection
           select{
               Foo = item.SomeField,
               Bar = item.SomeOtherField,
           }).ToList();

那么接下来是一些关于附加属性的代码:

public static class DataGridUtilities
{
    public static IDictionary<string,string> GetColumnHeaders(
        DependencyObject obj)
    {
        return (IDictionary<string,string>)obj.GetValue(ColumnHeadersProperty);
    }

    public static void SetColumnHeaders(DependencyObject obj,
        IDictionary<string, string> value)
    {
        obj.SetValue(ColumnHeadersProperty, value);
    }

    public static readonly DependencyProperty ColumnHeadersProperty =
        DependencyProperty.RegisterAttached(
            "ColumnHeaders",
            typeof(IDictionary<string, string>),
            typeof(DataGrid),
            new UIPropertyMetadata(null, ColumnHeadersPropertyChanged));

    static void ColumnHeadersPropertyChanged(DependencyObject sender,
        DependencyPropertyChangedEventArgs e)
    {
        var dataGrid = sender as DataGrid;
        if (dataGrid != null && e.NewValue != null)
        {
            dataGrid.AutoGeneratingColumn += AddColumnHeaders;
        }
    }

    static void AddColumnHeaders(object sender,
        DataGridAutoGeneratingColumnEventArgs e)
    {
        var headers = GetColumnHeaders(sender as DataGrid);
        if (headers != null && headers.ContainsKey(e.PropertyName))
        {
            e.Column.Header = headers[e.PropertyName];
        }
    }
}

+1 这可能是解决这个问题的好方法。我会尝试并发布反馈。谢谢。 - TheOtherGuy

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