Repeater and add columns to header and itemtemplate on page load
Use nested Repeaters: the outer Repeater is for rows and has a HeaderTemplate and ItemTemplate which contain inner Repeaters for header and checkbox columns respectively. Something like this:
<asp:Repeater runat="server" ID="rowRepeater" OnItemDataBound="rowRepeater_ItemBound">
<HeaderTemplate>
<table>
<tr>
<asp:Repeater runat="server" ID="headerRepeater">
<ItemTemplate>
<th>
<%# Container.DataItem %>
</th>
</ItemTemplate>
</asp:Repeater>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:Label runat="server" ID="lblUserName" Text='<%# Eval("Key") %>' /></td>
<asp:Repeater runat="server" ID="columnRepeater">
<ItemTemplate>
<td>
<asp:HiddenField runat="server" ID="hfRoleIndex" Value='<%# Container.ItemIndex %>' />
<asp:CheckBox runat="server" ID="cbColumnValue" Checked='<%# Container.DataItem %>' OnCheckedChanged="cbColumnValue_CheckedChanged" AutoPostBack="true" />
</td>
</ItemTemplate>
</asp:Repeater>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
and in your code behind:
Dictionary<string, bool[]> userRoles = new Dictionary<string, bool[]>(){
{"Bob", new bool[]{true,true,false,false}},
{"Tim",new bool[]{false,false,true,true}},
{"John",new bool[]{false,true,false,true}}
};
string[] headings = { "Rep Name", "Caller", "Closer", "Manager", "SuperUser" };
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
rowRepeater.DataSource = userRoles;
rowRepeater.DataBind();
}
}
protected void rowRepeater_ItemBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
Repeater headerRepeater = e.Item.FindControl("headerRepeater") as Repeater;
headerRepeater.DataSource = headings;
headerRepeater.DataBind();
}
else if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater columnRepeater = e.Item.FindControl("columnRepeater") as Repeater;
columnRepeater.DataSource = ((KeyValuePair<string, bool[]>)e.Item.DataItem).Value;
columnRepeater.DataBind();
}
}
protected void cbColumnValue_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
HiddenField hf = cb.Parent.FindControl("hfRoleIndex") as HiddenField;
int roleIndex = int.Parse(hf.Value); // now you have the column identifier
Label lbl = cb.Parent.Parent.Parent.FindControl("lblUserName") as Label;
string userName = lbl.Text; //now you have the row identifier
//now you can update your data source
userRoles[userName][roleIndex] = cb.Checked;
}
sdmiller
Obsessive Software developer who relaxes by writing code. Something is wrong with me!
Updated on June 19, 2022Comments
-
sdmiller almost 2 years
I haven't used repeaters for much more than showing data from a datatable.
I am building a grid that that shows a list of users and columns of roles that the user has been assigned, shown with checkboxes (shown with true/false below but pretent they are checkboxes).
ex.
|Rep Name|Caller|Closer|Manager|SuperUser|
|Bob |True |true | false | false |
|Tom |false |false |True | True |Basically using it for roles management.
However the roles may change later on so I want to load the roles(headers and items) dynamically into the repeater.
I am not sure how to do this or if it is even possible.
I figure you grab a list of current role possibilities and load them into the headertemplate but I am not sure how to match those with the itemtemplate and how to create checkboxes and place them in the itemtemplate.
Sorry if it is a rudementary question.... I appreciate any advice!
Datatable example of data that I am going to get... though I will also return ids for roles and users that are not shown here.
DataTable dt = new DataTable(); DataColumn dc = new DataColumn();
dc.DataType = Type.GetType("System.String"); dc.ColumnName = "RepName"; dt.Columns.Add(dc); dc = new DataColumn(); dc.DataType = Type.GetType("System.Boolean"); dc.ColumnName = "Caller"; dt.Columns.Add(dc); dc = new DataColumn(); dc.DataType = Type.GetType("System.Boolean"); dc.ColumnName = "closer"; dt.Columns.Add(dc); dc = new DataColumn(); dc.DataType = Type.GetType("System.Boolean"); dc.ColumnName = "Admin"; dt.Columns.Add(dc); dc = new DataColumn(); dc.DataType = Type.GetType("System.Boolean"); dc.ColumnName = "SuperUser"; dt.Columns.Add(dc); DataRow row; row = dt.NewRow(); row["RepName"] = "Joe"; row["Caller"] = true; row["closer"] = false; row["Admin"] = true; row["SuperUser"] = false; dt.Rows.Add(row); row = dt.NewRow(); row["RepName"] = "Bob"; row["Caller"] = true; row["closer"] = false; row["Admin"] = true; row["SuperUser"] = false; dt.Rows.Add(row); row = dt.NewRow(); row["RepName"] = "Tom"; row["Caller"] = true; row["closer"] = false; row["Admin"] = true; row["SuperUser"] = false; dt.Rows.Add(row);