【问题标题】:Binding a object with a sub objects as properties to a datagrid将具有子对象的对象作为属性绑定到数据网格
【发布时间】:2009-01-02 15:44:54
【问题描述】:

我正在处理一个包含子对象的对象(参见下面的示例)。我正在尝试将List<rootClass> 绑定到数据网格。当我绑定List<> 时,在包含subObject 的单元格中,我看到以下值... "namespace.subObject" ... 字符串值正确显示。

理想情况下,我希望在数据单元中查看subObject 的“描述”属性。如何将subObject.Description 映射到数据单元格中显示?

public class subObject
{
   int id;
   string description;

   public string Description
   { get { return description; } }
}

public class rootClass
{
   string value1;
   subObject value2;
   string value3;

   public string Value1
   { get { return value1; } }

   public subObject Value2
   { get { return value2; } }

   public string Value3
   { get { return value3; } }
}

【问题讨论】:

  • 这是我非常讨厌的 DGV 的缺点之一,也是为什么我几乎总是绑定到匿名类型的 IEnumerable。

标签: c# datagrid binding object datagridviewcolumn


【解决方案1】:

既然你提到DataGridViewColumn(标签),我假设你的意思是winforms。

访问子属性很痛苦;货币管理器绑定到列表,因此默认情况下您只能访问即时属性;但是,如果你绝对需要,你可以通过使用自定义类型描述符来解决这个问题。您还需要使用不同的令牌,例如“Foo_Bar”而不是“Foo.Bar”。然而,这是一项主要工作,需要了解PropertyDescriptorICustomTypeDescriptor 和可能TypeDescriptionProvider,而且几乎可以肯定不值得,

最简单的解决方法是将属性公开为 shim / pass-thru:

public string Value2Description {
    get {return Value2.Description;} // maybe a null check too
}

然后绑定到“Value2Description”等

【讨论】:

    【解决方案2】:

    如果我没记错的话,它会显示在您的子对象上调用 .ToString() 的结果,因此您可以覆盖它以返回 Description 的内容。

    您是否尝试过仅绑定到 Value1.Description? (我猜它不起作用)。

    我有一个类可以在绑定时代替 List 使用,它将处理这个问题,它实现了 ITypedList,它允许集合为其对象提供更多“属性”,包括计算属性。

    我拥有的文件的最新版本在这里:

    https://gist.github.com/lassevk/64ecea836116882a5d59b0f235858044

    使用方法:

    List<rootClass> yourList = ...
    TypedListWrapper<rootClass> bindableList = new TypedListWrapper<rootClass>(yourList);
    bindableList.BindableProperties = "Value1;Value2.Description;Value3.Description";
    gridView1.DataSource = bindableList;
    

    基本上,您绑定到 TypedList&lt;T&gt; 的实例而不是 List&lt;T&gt;,并调整 BindableProperties 属性。我对工作进行了一些更改,包括一个只是在运行时自动构建 BindableProperties,但它还没有放在主干中。

    您还可以添加计算属性,如下所示:

    yourList.AddCalculatedProperty<Int32>("DescriptionLength",
        delegate(rootClass rc)
        {
            return rc.Value2.Description.Length;
        });
    

    或使用 .NET 3.5:

    yourList.AddCalculatedProperty<Int32>("DescriptionLength",
        rc => rc.Value2.Description.Length);
    

    【讨论】:

    • 仅供参考,ITypedList主要是1.1;在 2.0 中,您可以在基础类型(即 List 中的 T)上使用 TypeDescriptionProvider 来做同样的事情。
    • 很高兴看到我不是唯一一个探索过 TypeDescriptor 深度的傻瓜;-p
    • 然后我会调查 TypeDescriptionProvider :)
    • 如果您查看HyperDescriptor 代码(只需搜索),您可以获得快速介绍。一旦你掌握了 GetProperties(),它应该很熟悉;-p
    • Lasse,我知道这个问题已经过时了,但您是否仍将源代码保留在网上可用的地方?上面的url返回500错误,我对TypedList代码很感兴趣?
    【解决方案3】:

    我不确定您是否使用 ASP.NET,但如果是,那么您可以使用模板列和 Eval() 方法来显示嵌套对象的值。例如。显示子对象的描述属性:

    <asp:GridView ID="grid" runat="server" AutoGenerateColumns="true">
      <Columns>
        <asp:TemplateField>
          <ItemTemplate>
            <asp:Literal Text='<%# Eval("Value2.Description") %>' runat="server" />
          </ItemTemplate>
        </asp:TemplateField>
      </Columns>
    </asp:GridView>
    

    【讨论】:

      【解决方案4】:

      不知道你是不是这样的......

      你可以写这样的方法:

      protected string getSubObject(object o)
      {
          string result = string.empty;
      
          try
          {
              result = ((subObject)o).Description;
          }
          catch
          { /*Do something here to handle/log your exception*/ } 
      
          return result;
      }
      

      然后像这样绑定对象:

      <asp:Literal Text='<%# getSubObject(Eval("Value2")) %>' runat="server" />
      

      【讨论】:

        猜你喜欢
        • 2011-07-08
        • 1970-01-01
        • 2014-10-29
        • 2011-03-29
        • 2020-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多