使用对象数据填充 GridView

发布于 2024-12-12 09:24:15 字数 2548 浏览 2 评论 0原文

想知道用我的对象数据填充 GridView 的最佳方法。

我必须显示来自复杂对象 Sale 的产品列表,其结构如下所示:

class Sale {
    int id;
    List<SaleItem> saleItems;
}

class SaleItem {
    int id;
    int quantity;
    Product product;

    BillingAddress billingAddress;
    ShippingAddress shippingAddress;
}

class Product {
    int id;
    string name;
    List<BuyingConfiguration> buyingConfigurations;
}

class BuyingConfiguration {
    string name; // like size, color, material
    string value;
}

我的网格应如下所示:

Sale Items
+---------+---+------------+------------+----------------+
| Name    | # | B. Address | S. Address | Configurations |
+---------+---+------------+------------+----------------+
| Ferrari | 2 | --         | --         | Color: red     |
|         |   |            |            | Engine: Xyz    |
+---------+---+------------+------------+----------------+
| Jax     | 1 | --         | --         | Color: blue    |
|         |   |            |            | Engine: Abc    |
+---------+---+------------+------------+----------------+

我应该为我的 Sale 实现一个 ObjectDataSource目的?还有更好的解决办法吗?


编辑2:让我试着澄清一下:问题不在于如何显示配置。 我的问题是 Sale 对象从持久层返回到我的代码,这就是我不希望 GridView 直接访问数据库的原因。相反,它需要从我的 Sale 对象加载所有数据,如何实现?


编辑:

按要求的网格标记:

<asp:GridView runat="server" ID="GridProdutos" OnRowDataBound="GridProdutos_OnRowDataBound"
    AutoGenerateColumns="False">
    <Columns>
        <asp:BoundField HeaderText="Name" />
        <asp:BoundField HeaderText="#" />
        <asp:BoundField HeaderText="B. Address" />
        <asp:BoundField HeaderText="S. Address" />
        <asp:BoundField HeaderText="Configurations" />
    </Columns>
</asp:GridView>

到目前为止,使用 OnRowDataBound 的丑陋解决方案(我想避免这种情况!):

protected void GridProdutos_OnRowDataBound(object sender, GridViewRowEventArgs e) {
    if (e.Row.DataItem == null)
        return;

    SaleItem item = (SaleItem )e.Row.DataItem;

    e.Row.Cells[0].Text = item.product.name;
    e.Row.Cells[1].Text = item.quantity.ToString();

    StringBuilder sbConfigurations = new StringBuilder();

    foreach (BuyingConfiguration configurationItem in item.product.buyingConfigurations) {
        sbConfigurations.AppendFormat("{0}: {1}<br />", configurationItem.name, configurationItem.value);
    }
    e.Row.Cells[4].Text = sbConfigurations .ToString();
}

Wondering the best way to populate a GridView with my object data.

I have to show a product list from an complex object Sale, whose structure is something like this:

class Sale {
    int id;
    List<SaleItem> saleItems;
}

class SaleItem {
    int id;
    int quantity;
    Product product;

    BillingAddress billingAddress;
    ShippingAddress shippingAddress;
}

class Product {
    int id;
    string name;
    List<BuyingConfiguration> buyingConfigurations;
}

class BuyingConfiguration {
    string name; // like size, color, material
    string value;
}

and my grid should look like this:

Sale Items
+---------+---+------------+------------+----------------+
| Name    | # | B. Address | S. Address | Configurations |
+---------+---+------------+------------+----------------+
| Ferrari | 2 | --         | --         | Color: red     |
|         |   |            |            | Engine: Xyz    |
+---------+---+------------+------------+----------------+
| Jax     | 1 | --         | --         | Color: blue    |
|         |   |            |            | Engine: Abc    |
+---------+---+------------+------------+----------------+

Should I implement an ObjectDataSource for my Sale object? Is there any better solution?


EDIT 2: Let me try to make myself clear: the problem is not how to the display configurations.
My problem is that the Sale object is returned to my code from the persistence layer, thats the why I dont want the GridView to access Database directly. Instead, it needs to load all its data from my Sale object, how to achieve that?


EDIT:

The Grid markup as requested:

<asp:GridView runat="server" ID="GridProdutos" OnRowDataBound="GridProdutos_OnRowDataBound"
    AutoGenerateColumns="False">
    <Columns>
        <asp:BoundField HeaderText="Name" />
        <asp:BoundField HeaderText="#" />
        <asp:BoundField HeaderText="B. Address" />
        <asp:BoundField HeaderText="S. Address" />
        <asp:BoundField HeaderText="Configurations" />
    </Columns>
</asp:GridView>

Ugly solution so far, using OnRowDataBound (I want to avoid that!):

protected void GridProdutos_OnRowDataBound(object sender, GridViewRowEventArgs e) {
    if (e.Row.DataItem == null)
        return;

    SaleItem item = (SaleItem )e.Row.DataItem;

    e.Row.Cells[0].Text = item.product.name;
    e.Row.Cells[1].Text = item.quantity.ToString();

    StringBuilder sbConfigurations = new StringBuilder();

    foreach (BuyingConfiguration configurationItem in item.product.buyingConfigurations) {
        sbConfigurations.AppendFormat("{0}: {1}<br />", configurationItem.name, configurationItem.value);
    }
    e.Row.Cells[4].Text = sbConfigurations .ToString();
}

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

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

发布评论

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

评论(2

阳光下的泡沫是彩色的 2024-12-19 09:24:15

我建议将 TemplateColumns 与绑定表达式一起使用。您可以将 GridView 绑定到 saleItems 列表,并实现 getter 方法来呈现给定 SaleItem 实例的每个字段。例如,您的 Name 列可以定义如下:

            <asp:TemplateField>
                <ItemTemplate>
                    <%# ((SaleItem)Container.DataItem).product.Name %>
                </ItemTemplate>
            </asp:TemplateField>

使用自定义 getter 方法可以完成相同的操作,将访问详细信息移动到代码隐藏中:

            <asp:TemplateField>
                <ItemTemplate>
                    <%# getSaleItemProductName((SaleItem)Container.DataItem) %>
                </ItemTemplate>
            </asp:TemplateField>

不要忘记添加 Import 指令以便能够引用您的类型:

<%@ Import Namespace="YouNamespaceHere" %>

I would suggest using the TemplateColumns with binding expressions. You can bind your GridView to the saleItems list, and implement getter methods to render each field given a SaleItem instance. For example, your Name column could be defined as follows:

            <asp:TemplateField>
                <ItemTemplate>
                    <%# ((SaleItem)Container.DataItem).product.Name %>
                </ItemTemplate>
            </asp:TemplateField>

The same thing could be done with a custom getter method to move the access details into the code-behind:

            <asp:TemplateField>
                <ItemTemplate>
                    <%# getSaleItemProductName((SaleItem)Container.DataItem) %>
                </ItemTemplate>
            </asp:TemplateField>

Don't forget to add an Import directive to be able to reference your types:

<%@ Import Namespace="YouNamespaceHere" %>
小兔几 2024-12-19 09:24:15
  dataGridView1.DataSource = ToDataTable(SaleItems);

如果您可以将复杂对象列表转换为数据表,则可以将数据直接绑定到 dataGridView,如下所示

 private DataTable ToDataTable(List<Sale> SaleItems)
    {
        DataTable returnTable = new DataTable("Sale");
        returnTable.Columns.Add(new DataColumn("Name"));
        returnTable.Columns.Add(new DataColumn("#"));
        returnTable.Columns.Add(new DataColumn("B. Address"));
        returnTable.Columns.Add(new DataColumn("S. Address"));
        returnTable.Columns.Add(new DataColumn("Configurations"));

        foreach (Sale item in SaleItems)
        {
            returnTable.AcceptChanges();
            DataRow row = returnTable.NewRow();
            row[0] = item.product.name;
            row[1] = item.quantity.ToString();
            row[2] = item.billingAddress.ToString();
            row[3] = item.billingAddress.ToString();
            StringBuilder sbConfigurations = new StringBuilder();

            foreach (BuyingConfiguration configurationItem in item.product.buyingConfigurations) {
               sbConfigurations.AppendFormat("{0}: {1}<br />", configurationItem.name, configurationItem.value);
            }
            row[4] = sbConfigurations.ToString();

            returnTable.Rows.Add(row);
        }
        return returnTable;
    }
  dataGridView1.DataSource = ToDataTable(SaleItems);

you can bind data directly to dataGridView if you can convert complex object list to Datatable as bellow

 private DataTable ToDataTable(List<Sale> SaleItems)
    {
        DataTable returnTable = new DataTable("Sale");
        returnTable.Columns.Add(new DataColumn("Name"));
        returnTable.Columns.Add(new DataColumn("#"));
        returnTable.Columns.Add(new DataColumn("B. Address"));
        returnTable.Columns.Add(new DataColumn("S. Address"));
        returnTable.Columns.Add(new DataColumn("Configurations"));

        foreach (Sale item in SaleItems)
        {
            returnTable.AcceptChanges();
            DataRow row = returnTable.NewRow();
            row[0] = item.product.name;
            row[1] = item.quantity.ToString();
            row[2] = item.billingAddress.ToString();
            row[3] = item.billingAddress.ToString();
            StringBuilder sbConfigurations = new StringBuilder();

            foreach (BuyingConfiguration configurationItem in item.product.buyingConfigurations) {
               sbConfigurations.AppendFormat("{0}: {1}<br />", configurationItem.name, configurationItem.value);
            }
            row[4] = sbConfigurations.ToString();

            returnTable.Rows.Add(row);
        }
        return returnTable;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文