C# 中继器对单个数据库中的项目进行分组

C# 中继器对单个数据库中的项目进行分组,c#,asp.net,repeater,C#,Asp.net,Repeater,我有一个带有标题的表(示例):Group、DisplayName、EditableData、description。 在过去的几天里,我一直在尝试学习Repeater,根据组对信息进行排序,这样我就可以得到如下布局。这是一个用户控件,我正试图把它们放在一起 Group1 ------------------ Name1 EditableData Some Description Name2 EditableData Some Description Group2 -

我有一个带有标题的表(示例):Group、DisplayName、EditableData、description。 在过去的几天里,我一直在尝试学习Repeater,根据组对信息进行排序,这样我就可以得到如下布局。这是一个用户控件,我正试图把它们放在一起

Group1
------------------
Name1     EditableData    Some Description
Name2     EditableData    Some Description

Group2
------------------
Name3     EditableData    Some Description
Name4     EditableData    Some Description
我在网上查看了以下其他示例: 和

我相信我没有正确地理解中继器如何工作到足以处理嵌套或数据源

<asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
        Group: <%#Eval("Group")%><br />
        <%--Nested Repeater would go here for all the children info for each "Group"--%>
    </ItemTemplate>
</asp:Repeater>

组:
在我的SQL中使用DISTINCT只检索“Group”只会给我留下正确的组,而不需要重复,我想我可以改为在标签中设置组,然后为每个特定的标签创建重复器。。。当我以后可能会将editableData更新回数据库时,这看起来很糟糕


我想我真正想要的至少是一个到演练的链接,该演练解释了中继器如何与Eval()和数据源一起工作。我的意思是,完成项目第一步所需的一切代码都是完美的;P但我也希望能够更好地理解这些,因为我可能会在不久的将来经常使用它们。

我曾经遇到过同样的问题,我要按组对数据进行排序,并且我必须在分组段中显示常用项

当然,有多种方法可以检索数据,例如,您可以获取不同的组名并将其绑定到中继器,然后在
ItemDataBound
事件上执行并获取类似以下内容的其他元素:

<asp:Repeater runat="server" ID="rptrGroups" OnItemDataBound="rptrGroups_ItemDataBound">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv">
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>

protected void rptrGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item)
    {
        var lblGroupName = (Label)e.Item.FindControl("lblGroupName");
        GridView gv = (GridView)e.Item.FindControl("table");

        var dataTable = FetchDataWithGroupName(lblGroupName.Text); // Method that fetches data with groupname.
        gv.DataSource = dataTable;
        gv.DataBind();
    }
}
<asp:Repeater runat="server" ID="rptrGroups">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv" DataSource='<%# ((GroupedModel)Container.DataItem).TableData %>'>
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>
    Dim strSQL As String = 
       "SELECT ID, FirstName, LastName, HotelName, City FROM tblHotels ORDER BY City, HotelName"

    GridView1.DataSource = Myrst(strSQL)
    GridView1.DataBind()
    If e.Row.RowType = DataControlRowType.DataRow Then

        ' if grouping = 1 then create a new row!
        Dim gvRow As DataRowView = DirectCast(e.Row.DataItem, DataRowView)

        If gvRow("City") <> LastCity Then
            LastCity = gvRow("City")

            ' insert a new row for grouping header
            Dim MyRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
            Dim MyCel As New TableCell()
            'MyCel.Width = Unit.Percentage(100)
            Dim MyTable As Table = e.Row.Parent

            MyCel.ColumnSpan = MyTable.Rows(0).Controls.Count
            Dim MyLable As New Label
            MyLable.Text = "<h2>" & gvRow("City") & "</h2>"
            MyCel.Controls.Add(MyLable)
            MyRow.Cells.Add(MyCel)
            MyTable.Rows.AddAt(MyTable.Rows.Count - 1, MyRow)

        End If

    End If
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
  <Columns>
    <asp:BoundField DataField="City" HeaderText="City" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
     <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
     <asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
   </Columns>
</asp:GridView>
然后按如下方式修改标记:

<asp:Repeater runat="server" ID="rptrGroups" OnItemDataBound="rptrGroups_ItemDataBound">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv">
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>

protected void rptrGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item)
    {
        var lblGroupName = (Label)e.Item.FindControl("lblGroupName");
        GridView gv = (GridView)e.Item.FindControl("table");

        var dataTable = FetchDataWithGroupName(lblGroupName.Text); // Method that fetches data with groupname.
        gv.DataSource = dataTable;
        gv.DataBind();
    }
}
<asp:Repeater runat="server" ID="rptrGroups">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv" DataSource='<%# ((GroupedModel)Container.DataItem).TableData %>'>
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>
    Dim strSQL As String = 
       "SELECT ID, FirstName, LastName, HotelName, City FROM tblHotels ORDER BY City, HotelName"

    GridView1.DataSource = Myrst(strSQL)
    GridView1.DataBind()
    If e.Row.RowType = DataControlRowType.DataRow Then

        ' if grouping = 1 then create a new row!
        Dim gvRow As DataRowView = DirectCast(e.Row.DataItem, DataRowView)

        If gvRow("City") <> LastCity Then
            LastCity = gvRow("City")

            ' insert a new row for grouping header
            Dim MyRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
            Dim MyCel As New TableCell()
            'MyCel.Width = Unit.Percentage(100)
            Dim MyTable As Table = e.Row.Parent

            MyCel.ColumnSpan = MyTable.Rows(0).Controls.Count
            Dim MyLable As New Label
            MyLable.Text = "<h2>" & gvRow("City") & "</h2>"
            MyCel.Controls.Add(MyLable)
            MyRow.Cells.Add(MyCel)
            MyTable.Rows.AddAt(MyTable.Rows.Count - 1, MyRow)

        End If

    End If
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
  <Columns>
    <asp:BoundField DataField="City" HeaderText="City" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
     <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
     <asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
   </Columns>
</asp:GridView>

我曾经遇到过同样的问题,我需要按组对数据进行排序,并且必须在分组段中显示公共项

当然,有多种方法可以检索数据,例如,您可以获取不同的组名并将其绑定到中继器,然后在
ItemDataBound
事件上执行并获取类似以下内容的其他元素:

<asp:Repeater runat="server" ID="rptrGroups" OnItemDataBound="rptrGroups_ItemDataBound">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv">
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>

protected void rptrGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item)
    {
        var lblGroupName = (Label)e.Item.FindControl("lblGroupName");
        GridView gv = (GridView)e.Item.FindControl("table");

        var dataTable = FetchDataWithGroupName(lblGroupName.Text); // Method that fetches data with groupname.
        gv.DataSource = dataTable;
        gv.DataBind();
    }
}
<asp:Repeater runat="server" ID="rptrGroups">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv" DataSource='<%# ((GroupedModel)Container.DataItem).TableData %>'>
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>
    Dim strSQL As String = 
       "SELECT ID, FirstName, LastName, HotelName, City FROM tblHotels ORDER BY City, HotelName"

    GridView1.DataSource = Myrst(strSQL)
    GridView1.DataBind()
    If e.Row.RowType = DataControlRowType.DataRow Then

        ' if grouping = 1 then create a new row!
        Dim gvRow As DataRowView = DirectCast(e.Row.DataItem, DataRowView)

        If gvRow("City") <> LastCity Then
            LastCity = gvRow("City")

            ' insert a new row for grouping header
            Dim MyRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
            Dim MyCel As New TableCell()
            'MyCel.Width = Unit.Percentage(100)
            Dim MyTable As Table = e.Row.Parent

            MyCel.ColumnSpan = MyTable.Rows(0).Controls.Count
            Dim MyLable As New Label
            MyLable.Text = "<h2>" & gvRow("City") & "</h2>"
            MyCel.Controls.Add(MyLable)
            MyRow.Cells.Add(MyCel)
            MyTable.Rows.AddAt(MyTable.Rows.Count - 1, MyRow)

        End If

    End If
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
  <Columns>
    <asp:BoundField DataField="City" HeaderText="City" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
     <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
     <asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
   </Columns>
</asp:GridView>
然后按如下方式修改标记:

<asp:Repeater runat="server" ID="rptrGroups" OnItemDataBound="rptrGroups_ItemDataBound">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv">
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>

protected void rptrGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item)
    {
        var lblGroupName = (Label)e.Item.FindControl("lblGroupName");
        GridView gv = (GridView)e.Item.FindControl("table");

        var dataTable = FetchDataWithGroupName(lblGroupName.Text); // Method that fetches data with groupname.
        gv.DataSource = dataTable;
        gv.DataBind();
    }
}
<asp:Repeater runat="server" ID="rptrGroups">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv" DataSource='<%# ((GroupedModel)Container.DataItem).TableData %>'>
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>
    Dim strSQL As String = 
       "SELECT ID, FirstName, LastName, HotelName, City FROM tblHotels ORDER BY City, HotelName"

    GridView1.DataSource = Myrst(strSQL)
    GridView1.DataBind()
    If e.Row.RowType = DataControlRowType.DataRow Then

        ' if grouping = 1 then create a new row!
        Dim gvRow As DataRowView = DirectCast(e.Row.DataItem, DataRowView)

        If gvRow("City") <> LastCity Then
            LastCity = gvRow("City")

            ' insert a new row for grouping header
            Dim MyRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
            Dim MyCel As New TableCell()
            'MyCel.Width = Unit.Percentage(100)
            Dim MyTable As Table = e.Row.Parent

            MyCel.ColumnSpan = MyTable.Rows(0).Controls.Count
            Dim MyLable As New Label
            MyLable.Text = "<h2>" & gvRow("City") & "</h2>"
            MyCel.Controls.Add(MyLable)
            MyRow.Cells.Add(MyCel)
            MyTable.Rows.AddAt(MyTable.Rows.Count - 1, MyRow)

        End If

    End If
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
  <Columns>
    <asp:BoundField DataField="City" HeaderText="City" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
     <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
     <asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
   </Columns>
</asp:GridView>

我发现只使用gridview或list视图效果相当不错。但是,不要尝试使用分组功能,因为它用于在页面上而不是向下放置项目

让我们把它变得非常简单

好的,我有一个酒店列表,但我想按城市分组

因此,您可以构建如下查询:

<asp:Repeater runat="server" ID="rptrGroups" OnItemDataBound="rptrGroups_ItemDataBound">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv">
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>

protected void rptrGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item)
    {
        var lblGroupName = (Label)e.Item.FindControl("lblGroupName");
        GridView gv = (GridView)e.Item.FindControl("table");

        var dataTable = FetchDataWithGroupName(lblGroupName.Text); // Method that fetches data with groupname.
        gv.DataSource = dataTable;
        gv.DataBind();
    }
}
<asp:Repeater runat="server" ID="rptrGroups">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv" DataSource='<%# ((GroupedModel)Container.DataItem).TableData %>'>
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>
    Dim strSQL As String = 
       "SELECT ID, FirstName, LastName, HotelName, City FROM tblHotels ORDER BY City, HotelName"

    GridView1.DataSource = Myrst(strSQL)
    GridView1.DataBind()
    If e.Row.RowType = DataControlRowType.DataRow Then

        ' if grouping = 1 then create a new row!
        Dim gvRow As DataRowView = DirectCast(e.Row.DataItem, DataRowView)

        If gvRow("City") <> LastCity Then
            LastCity = gvRow("City")

            ' insert a new row for grouping header
            Dim MyRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
            Dim MyCel As New TableCell()
            'MyCel.Width = Unit.Percentage(100)
            Dim MyTable As Table = e.Row.Parent

            MyCel.ColumnSpan = MyTable.Rows(0).Controls.Count
            Dim MyLable As New Label
            MyLable.Text = "<h2>" & gvRow("City") & "</h2>"
            MyCel.Controls.Add(MyLable)
            MyRow.Cells.Add(MyCel)
            MyTable.Rows.AddAt(MyTable.Rows.Count - 1, MyRow)

        End If

    End If
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
  <Columns>
    <asp:BoundField DataField="City" HeaderText="City" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
     <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
     <asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
   </Columns>
</asp:GridView>
好的,这将填充我们的网格视图。我们得到这个:

到目前为止,有两行代码

但是,我们想按城市分组

因此,在forms类级别,添加简单变量:

Public Class HotelGroupGrid
    Inherits System.Web.UI.Page

    Dim LastCity As String    <----- this one

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If IsPostBack = False Then
            LastCity = ""
            Call LoadGrid()
        End If
    End Sub
Public Class HotelGroupGrid酒店
继承System.Web.UI.Page

Dim LastCity As String我发现只使用gridview或list视图效果相当不错。但是,不要尝试使用分组功能,因为它用于在页面上而不是向下放置项目

让我们把它变得非常简单

好的,我有一个酒店列表,但我想按城市分组

因此,您可以构建如下查询:

<asp:Repeater runat="server" ID="rptrGroups" OnItemDataBound="rptrGroups_ItemDataBound">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv">
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>

protected void rptrGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item)
    {
        var lblGroupName = (Label)e.Item.FindControl("lblGroupName");
        GridView gv = (GridView)e.Item.FindControl("table");

        var dataTable = FetchDataWithGroupName(lblGroupName.Text); // Method that fetches data with groupname.
        gv.DataSource = dataTable;
        gv.DataBind();
    }
}
<asp:Repeater runat="server" ID="rptrGroups">
    <ItemTemplate>
        <asp:Label runat="server" ID="lblGroupName" Text='<%# Eval("GroupName") %>' />

        <asp:GridView runat="server" ID="gv" DataSource='<%# ((GroupedModel)Container.DataItem).TableData %>'>
        </asp:GridView>
    </ItemTemplate>
</asp:Repeater>
    Dim strSQL As String = 
       "SELECT ID, FirstName, LastName, HotelName, City FROM tblHotels ORDER BY City, HotelName"

    GridView1.DataSource = Myrst(strSQL)
    GridView1.DataBind()
    If e.Row.RowType = DataControlRowType.DataRow Then

        ' if grouping = 1 then create a new row!
        Dim gvRow As DataRowView = DirectCast(e.Row.DataItem, DataRowView)

        If gvRow("City") <> LastCity Then
            LastCity = gvRow("City")

            ' insert a new row for grouping header
            Dim MyRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
            Dim MyCel As New TableCell()
            'MyCel.Width = Unit.Percentage(100)
            Dim MyTable As Table = e.Row.Parent

            MyCel.ColumnSpan = MyTable.Rows(0).Controls.Count
            Dim MyLable As New Label
            MyLable.Text = "<h2>" & gvRow("City") & "</h2>"
            MyCel.Controls.Add(MyLable)
            MyRow.Cells.Add(MyCel)
            MyTable.Rows.AddAt(MyTable.Rows.Count - 1, MyRow)

        End If

    End If
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
  <Columns>
    <asp:BoundField DataField="City" HeaderText="City" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
     <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
     <asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
   </Columns>
</asp:GridView>
好的,这将填充我们的网格视图。我们得到这个:

到目前为止,有两行代码

但是,我们想按城市分组

因此,在forms类级别,添加简单变量:

Public Class HotelGroupGrid
    Inherits System.Web.UI.Page

    Dim LastCity As String    <----- this one

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If IsPostBack = False Then
            LastCity = ""
            Call LoadGrid()
        End If
    End Sub
Public Class HotelGroupGrid酒店
继承System.Web.UI.Page

Dim LastCity作为字符串我建议您使用listview或grid视图。不需要中继器。对于标题,只需将该行作为单独的行添加到网格中,然后在item data bind事件中,只需隐藏或显示另一行作为分组标题。GroupByExpressions和GroupByFields使这一切进展迅速。Jamshaid的答案是基于重复的,而Albert在listview上的帖子是我从未考虑过的。。。看起来很简单。我建议您使用列表视图或网格视图。不需要中继器。对于标题,只需将该行作为单独的行添加到网格中,然后在item data bind事件中,只需隐藏或显示另一行作为分组标题。GroupByExpressions和GroupByFields使这一切进展迅速。Jamshaid的答案是基于重复的,而Albert在listview上的帖子是我从未考虑过的。。。看起来真的很容易。