3

在此处输入图像描述

我正在使用 asp 转发器来显示名称列表,并且我想将当前字母显示为一种分组标题,就像在索引页面中一样。

数据在绑定之前按字母顺序排序,但我发现在显示名称之前很难插入“A”和“B”。

4

5 回答 5

2

在绑定之前进行排序。

即绑定排序后的结果集。

然而,如果没有看到你所拥有的价值观,就不可能确切地知道如何做到这一点。


更新-根据您的评论,我会说您需要将绑定源更改为类似Dictionary<string,IList<string>>.

使用这样的结构,您可以通过键(排序)和子列表(二级排序)进行绑定。

于 2013-02-12T14:04:48.740 回答
2

将 Panel 控件添加到您的 ItemTemplate,并将可见性设置为 False。当您绑定中继器时(假设您正在订阅ItemDataBound事件),运行检查以查看第一个字母是否已更改。如果有,请将面板的可见性设置为 true 并打印出该字母。

如果您需要一些示例代码,请告诉我。

编辑:示例代码

为清楚起见,“AlphaHeaders”就是我们要显示的“A”、“B”、“C”字母

aspx 代码

中继器将如下所示:

<table>
    <asp:Repeater id="rptRepeater" runat="server" OnItemDataBound="rptNames_OnItemDataBound">
        <ItemTemplate>
            <asp:Panel id="pnlAlphaHeader" runat="server" visible="False">
               <tr><td><asp:Label id="lblAlphaHeader" runat="server" /></td></tr>
            </asp:Panel>
            <tr><td><asp:Label id="lblName" runat="server" /></td></tr>
        </ItemTemplate>
    </asp:Repeater>
</table>

aspx.cs 代码

首先,您需要一个保存当前 AlphaHeader 的变量:

private string _AlphaHeaderCurrent = String.Empty;

然后,您将对转发器的OnItemDataBound事件进行处理:

protected void rptNames_OnItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
   if ((e.ItemType==ListItemType.Item) || (e.ItemType==ListItemType.AlternatingItem)) {
      string name = e.Item.DataItem("Name").ToString();
      //check if the first letter of the current name is new. If it is new, we print out the header
      if(!name.StartsWith(this._AlphaHeaderCurrent)) {
         this._AlphaHeaderCurrent = name.SubString(1);                               
         ((Panel)e.ItemFindControl("pnlAlphaHeader")).Visible = true;
         ((Label)e.Item.FindControl("lblAlphaHeader")).Text = the._AlphaHeader;
      }
      ((Label)e.Item.FindControl("lblName")).Text = name;          
   }
}
于 2013-02-12T17:36:16.653 回答
1

在将数据绑定到中继器之前,您需要对数据进行排序。

于 2013-02-12T14:05:42.390 回答
1

您可以使用嵌套中继器(中继器内的中继器)。像类别和子类别。在第一个中继器中,您可以列出所有名称并以 A 开头。然后在子中继器中,您可以显示所有名称。您还将使用 itemdatabound 事件绑定第二个中继器。

<asp:Repeater id="rptFirstLetters" runat="server" OnItemDataBound="rptChars_OnItemDataBound">
<ItemTemplate>
    <div>"<%#Eval("letters") %>"
        <asp:Repeater id="rptNames" runat="server">
            <ItemTemplate>
                <%#Eval("names") %>
            </ItemTemplate>
        </asp:Repeater>         
    </div> // bind all letters
</ItemTemplate>

于 2013-02-12T14:14:52.307 回答
1

老实说,这并不是一个很好的方法,中继器通常会导致我发现的丑陋代码。如果可以设置,来自 kad1r 的分层方法可能是最好的,但也有其他选择,具体取决于您的实现细节;我在某些方面更喜欢这个,因为它可以保持标记非常干净,而且我有一个非程序员设计人员,这对我来说是一个加分项。

ASPX:

<%@ Page language="C#" Src="test.CODE.cs" Inherits="test_Page" %>
<asp:Repeater ID="TestRepeater" runat="server">
    <ItemTemplate>
        <asp:PlaceHolder Visible='<%# Eval("IsFirstInGroup") %>' runat="server">
            <strong><%# Eval("Initial") %></strong><br/>
        </asp:PlaceHolder>
        <%# Eval("Name") %><br/>
    </ItemTemplate>
</asp:Repeater>

代码背后:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public class test_Page : Page
{
        protected Repeater TestRepeater;

        protected override void OnInit(EventArgs e)
        {
                base.OnInit(e);

                String[] names = new String[] 
                {        
                        "Alpha, John",
                        "Altman, Mary", 
                        "Asher, Cyril",
                        "Bachman, Turner",
                        "Beta, Rob",
                        "Bexman, Norah",
                        "Clark, Freddy"
                };

                List<_DispItem> l = new List<_DispItem>();

                for (int i = 0; i < names.Length; i++)
                        l.Add(new _DispItem() { Name = names[i], IsFirstInGroup = (i == 0 || names[i - 1][0] != names[i][0]) });

                TestRepeater.DataSource = l;
                TestRepeater.DataBind();
        }

        private class _DispItem
        {
                public String Name { get; set; }
                public String Initial { get { return Name.Substring(0, 1); } }
                public bool IsFirstInGroup { get; set; }
        }
}
于 2013-02-12T17:38:08.817 回答