将具有子对象的对象作为属性绑定到数据网格

发布于 2024-07-10 20:50:58 字数 746 浏览 12 评论 0原文

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

理想情况下,我希望在数据单元中看到 subObject 的“Description”属性。 如何映射 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; } }
}

I am working with an object which has sub objects within (see example below). I am attempting to bind a List<rootClass> to the datagrid. When I bind the List<>, in the cell that contains the subObject, I see the following value ... "namespace.subObject" ... the string values display correctly.

Ideally I would like to see the “Description” property of the subObject in the datacell. How can I map the subObject.Description to show in the datacell?

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; } }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

春庭雪 2024-07-17 20:50:58

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

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

最简单的解决方法是将属性公开为垫片/传递:

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

然后绑定到“Value2Description”等。

Since you mention DataGridViewColumn (tags), I assume you mean winforms.

Accessing sub-properties is a pain; the currency-manager is bound to the list, so you only have access to immediate properties by default; however, you can get past this if you absolutely need by using a custom type descriptor. You would need to use a different token too, like "Foo_Bar" instead of "Foo.Bar". However, this is a major amount of work that requires knowledge of PropertyDescriptor, ICustomTypeDescriptor and probably TypeDescriptionProvider, and almost certainly isn't worth it,

The simplest fix is to expose the property as a shim / pass-thru:

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

Then bind to "Value2Description" etc.

永言不败 2024-07-17 20:50:58

如果我没有记错的话,它显示了在子对象上调用 .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 而不是 List 的实例,并调整 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);

If I'm not mistaken, it shows the result of calling .ToString() on your subObject, so you can override that to return the contents of Description.

Have you tried just binding to Value1.Description? (I'm guessing it doesn't work).

I have a class that can be used instead of List when binding, that will handle this, it implements ITypedList, which allows a collection to provide more "properties" for its objects, including calculated properties.

The last version of the files I have are here:

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

To use:

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

Basically you bind to an instance of TypedList<T> instead of List<T>, and adjust the BindableProperties property. I have some changes in the work, including one that just builds up BindableProperties automatically as it goes, but it isn't in the trunk yet.

You can also add calculated properties, like this:

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

or with .NET 3.5:

yourList.AddCalculatedProperty<Int32>("DescriptionLength",
    rc => rc.Value2.Description.Length);
耀眼的星火 2024-07-17 20:50:58

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

<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>

I'm not sure whether you are using ASP.NET, but if yes, then you can use a template column and the Eval() method to display values of nested objects. E.g. to display the Description property of the subObject:

<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>
半葬歌 2024-07-17 20:50:58

不确定它是否是您想要的东西...

您可以编写如下方法:

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" />

Not sure if it's something like this you are after...

You could write a method like:

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;
}

Then bind the object something like this:

<asp:Literal Text='<%# getSubObject(Eval("Value2")) %>' runat="server" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文