C#中绑定Repeater控件出现重复数据问题求助
问题描述
使用Repeater控件尝试分组展示数据,但出现重复内容。当前显示效果:
存储过程返回的数据库数据:
已尝试将内容移到HeaderTemplate、绑定到列表等方法,问题仍未解决,寻求帮助。
Repeater控件代码
<asp:Repeater ID="GroupRepeater" OnItemDataBound="GroupRepeater_ItemDataBound" runat="server"> <HeaderTemplate> <asp:HiddenField ID="CompanyName" runat="server" /> </HeaderTemplate> <ItemTemplate> <div id="BoardGrpName"> <%# Eval("BoardGroupName") %> </div> <div id="BoardCompanyName1"> <%# Eval("CompanyName") %> </div> <div id="BoardCompanyName2"> <%# Eval("BoardMemberName") %> </div> <br /> </ItemTemplate> <FooterTemplate> <div class="label label-light" id="BoardMemberName"> <asp:Label ForeColor="Black" Font-Size="12px" runat="server"><%# Eval("BoardMemberName") %></asp:Label> </div> </FooterTemplate> </asp:Repeater>
后台代码(Code Behind)
protected void Page_Load(object sender, EventArgs e) { try { if (!Page.IsPostBack) { //load board members GroupRepeater.DataSource = DbHelper.SqlStoredProcedureDataTable("spQueryFullBoardInfo", ConfigurationManager.ConnectionStrings["NConnectionString"].ConnectionString); GroupRepeater.DataBind(); divMessage.Visible = false; } } catch (Exception ex) { catch error here } }
解决方案
Repeater本身无原生分组功能,当前重复显示是因为每条数据都渲染了BoardGroupName和CompanyName。以下两种方法可实现分组效果:
方法1:后台分组后绑定嵌套Repeater
先在后台对数据按分组字段聚合,再通过嵌套Repeater展示分组标题和下属成员。
- 定义分组模型
public class BoardGroup { public string BoardGroupName { get; set; } public string CompanyName { get; set; } public List<string> BoardMemberNames { get; set; } }
- 修改后台数据绑定逻辑
protected void Page_Load(object sender, EventArgs e) { try { if (!Page.IsPostBack) { DataTable dt = DbHelper.SqlStoredProcedureDataTable("spQueryFullBoardInfo", ConfigurationManager.ConnectionStrings["NConnectionString"].ConnectionString); // 按BoardGroupName+CompanyName分组 var groupedData = dt.AsEnumerable() .GroupBy(row => new { GroupName = row.Field<string>("BoardGroupName"), CompanyName = row.Field<string>("CompanyName") }) .Select(g => new BoardGroup { BoardGroupName = g.Key.GroupName, CompanyName = g.Key.CompanyName, BoardMemberNames = g.Select(row => row.Field<string>("BoardMemberName")).ToList() }) .ToList(); GroupRepeater.DataSource = groupedData; GroupRepeater.DataBind(); divMessage.Visible = false; } } catch (Exception ex) { // 异常处理逻辑 } }
- 修改Repeater为嵌套结构
<asp:Repeater ID="GroupRepeater" runat="server"> <ItemTemplate> <div id="BoardGrpName"> <%# Eval("BoardGroupName") %> </div> <div id="BoardCompanyName1"> <%# Eval("CompanyName") %> </div> <!-- 嵌套Repeater展示成员列表 --> <asp:Repeater ID="MemberRepeater" runat="server" DataSource='<%# Eval("BoardMemberNames") %>'> <ItemTemplate> <div id="BoardCompanyName2"> <%# Container.DataItem %> </div> </ItemTemplate> </asp:Repeater> <br /> </ItemTemplate> </asp:Repeater>
方法2:在ItemDataBound中控制分组标题显示
通过记录上一条数据的分组信息,判断当前项是否需要显示分组标题(需确保数据源已按分组字段排序)。
- 添加页面级变量记录上一分组
private string _lastGroupName = string.Empty; private string _lastCompanyName = string.Empty;
- 实现ItemDataBound事件
protected void GroupRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { DataRowView row = (DataRowView)e.Item.DataItem; string currentGroupName = row["BoardGroupName"].ToString(); string currentCompanyName = row["CompanyName"].ToString(); // 获取分组标题控件 Control groupNameDiv = e.Item.FindControl("BoardGrpName"); Control companyNameDiv = e.Item.FindControl("BoardCompanyName1"); // 与上一分组相同则隐藏标题 if (currentGroupName == _lastGroupName && currentCompanyName == _lastCompanyName) { groupNameDiv.Visible = false; companyNameDiv.Visible = false; } else { // 更新记录的分组信息 _lastGroupName = currentGroupName; _lastCompanyName = currentCompanyName; } } }
注意:需在存储过程中添加ORDER BY BoardGroupName, CompanyName,确保数据按分组字段排序,否则分组会混乱。
内容的提问来源于stack exchange,提问作者DotNetter
相关产品推荐
相关产品推荐

