【问题标题】:DisplayNameAttribute for anonymous class匿名类的 DisplayNameAttribute
【发布时间】:2011-06-02 19:51:25
【问题描述】:

如果我有这样一个非匿名类,我知道我可以像这样使用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 类。这里有使用匿名类的技术需求吗?
  • “由于一些不同的内部原因,我无法创建具体类” 没有理由不能创建新类。你的磁盘空间用完了还是什么?
  • 这并不是粗鲁,但如果我的组织内部有人说我无法创建课程,我会开始完善我的简历。
  • 嗯,主要原因之一是我有大约 70 个这样的查询,我不想为每个查询创建一个类,只是为了使用 DisplayNameAttribute。另一个原因是计划使用Dynamic Linq 来让用户在运行时选择列。
  • @TheOtherGuy 听起来您可能需要对数据库进行一些规范化。即使您可以选择返回哪些列,DAO 也可以包含所有内容,而未选择的内容将为空。我对用户选择所选列有意义的场景更加好奇。

标签: c# anonymous-types


【解决方案1】:

下面的解决方案怎么样:

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 这可能是解决这个问题的好方法。我会尝试并发布反馈。谢谢
【解决方案2】:

据我所知,您不能将属性应用于匿名类型。编译器根本不支持它。您可以真正离开马车并使用 Mono.Cecil 之类的东西作为构建后的步骤来将属性放在那里,但这几乎不是您想要考虑的事情。为什么一定要匿名?

【讨论】:

  • 感谢您的回答。我在问题 cmets 部分中包括了为什么我更喜欢匿名课程的主要原因。
猜你喜欢
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多