Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
377 views
in Technique[技术] by (71.8m points)

c# - Databind repeater using Linq with group by

I need to bind a repeater with hierarchical data as follows:

Category1
   - Item1
   - Item2
Category2
   - Item3
   - Item4

I currently have a single dataset with the items as well as the category that each item belongs to.

I'm trying to learn Linq and was wondering if there was a way I can do the same using Linq?

Below is what I tried:

var groupbyfilter = from dr in dtListing.AsEnumerable()
                            group dr by dr["Category"];
        DataTable dtFinal = dtListing.Clone();

  foreach (var x in groupbyfilter)
          x.CopyToDataTable(dtFinal, LoadOption.OverwriteChanges);


  rptList.DataSource = dtFinal;
  rptList.DataBind();

But trouble with it is it repeats category for each item.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You'll need a repeater nested inside another.

Do a distinct on the dtlisting selecting only the category field. Bind this to the outer repeater.

In the 2nd repeater, select data whose where condition has category field which equals to the value that is being databound to the repeater item. You'd have to handle this in the repeater's onitem_databound event.

Here is an example.

<%@ Import  Namespace="System.Data" %>
      <asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
          <ItemTemplate>
              <div>
                  Category: <b><%# Container.DataItem%></b>
                  <asp:Repeater ID="Repeater2" runat="server">
                      <FooterTemplate>
                          <%="</ul>" %>
                      </FooterTemplate>
                      <HeaderTemplate>
                          <%= "<ul>"%>
                      </HeaderTemplate>
                      <ItemTemplate>
                          <li>
                              <%# ((Data.DataRow)Container.DataItem)[1] %>, <%#  ((Data.DataRow)Container.DataItem)[0] %>
                          </li>
                      </ItemTemplate>
                  </asp:Repeater>
              </div>                
          </ItemTemplate>
      </asp:Repeater>

For this sample I used a csv as my datasource, and created a datatable using it. So my codebehind looks like:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;

public class _Default : System.Web.UI.Page
{
    DataTable csvData;
    protected void Page_Load(object sender, System.EventArgs e)
    {
        csvData = Utils.csvToDataTable("data.csv", true);
        GridView1.DataSource = csvData;
        GridView1.DataBind();

        Repeater1.DataSource =
            (from x in csvData.AsEnumerable() select x["category"]).Distinct();
        Repeater1.DataBind();
    }

    protected void Repeater1_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item |
                e.Item.ItemType == ListItemType.AlternatingItem) {
            Repeater rptr = (Repeater)e.Item.FindControl("Repeater2");
            rptr.DataSource =
                csvData.AsEnumerable().Where(x => x["category"].Equals(e.Item.DataItem));
            rptr.DataBind();
        }
    }       
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...