How to create a capitalized string for a list of names in an ASP repeater
Add a Panel control to your ItemTemplate with visibility set to False. When you link the relay (assuming you are subscribing to the event ItemDataBound
), run a check to see if the first letter has changed. If set, set panel visibility to true and print a letter.
Let me know if you need some sample code.
EDIT: CODE EXAMPLE
For clarity, "AlphaHeaders" are what we will call the letters "A", "B", "C" we want to display
aspx code
The repeater will look like this:
<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 code
First, you need a variable containing the current AlphaHeader:
private string _AlphaHeaderCurrent = String.Empty;
Then you do your work on the relay event 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;
}
}
source to share
Sort before binding.
That is, bind the sorted result set.
Without seeing the values ββthat you have, it's impossible to tell exactly how to do this.
Update - from comment , I would say you need to change the binding source to something like Dictionary<string,IList<string>>
.
With a structure like this, you can bind a key (sorted) and a sublist (secondary sort).
source to share
You can use nested repeaters (repeater inside a repeater). As a category and a subcategory. In the first repeater you can list all your names and make the condition start with A. Then in the sub-repeater you can show all the names. You will also use the itemdatabound event to bind the second relay.
<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>
source to share
Not a good way to do this, to be honest, repeaters usually lead to ugly code I have found. The hierarchical approach from kad1r is probably the nicest if you can customize it, but there are alternatives, depending on your implementation details; I kind of prefer this in some way since it keeps the markup very clean and since I have a boyfriend who is not a programmer which is a plus for me.
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>
CODE BEHIND:
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; }
}
}
source to share