i have been working on a project as i got stucked in one of the problem as,i have a repeater and radiobuttonlist inside it, i want to fill radiobuttonlist from my database but i am getting an error as object reference not set to the instance of an object.
aspx code
<asp:Repeater ID="Repeater1" runat="server"OnItemDataBound="fillRepeater_onitembound">
<HeaderTemplate>
</HeaderTemplate>
<AlternatingItemTemplate>
</AlternatingItemTemplate>
<ItemTemplate>
<table style="width:1100px">
<tr style="width:1100px">
<asp:Label ID="lbl_teachername" runat="server" Text='<%#Eval("teachername") %>' ></asp:Label>
<asp:Label ID="lbl_teachercode" runat="server" Text='<%#Eval("teachercode") %>' style="display:none;" ></asp:Label>
</tr>
<br />
<tr>
<td style="width:150px">
<asp:Image ID="img_teacher" runat="server" ImageUrl="~/Images/staff.png" Height="100px" Width="100px"/>
</td>
<td >
<asp:RadioButtonList ID="radioatt" runat="server" OnSelectedIndexChanged="radioatt_OnSelectedIndexChanged" AutoPostBack="true" >
</asp:RadioButtonList>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
c# code
protected void fillRepeater_onitembound(object sender,RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
sql = "select Description,AttendanceCode from tblattendancecodes";
ds = obj.openDataset(sql);
ListItem li;
RadioButtonList rbtl = (RadioButtonList)e.Item.FindControl("radioatt");
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
li = new ListItem();
li.Text = ds.Tables[0].Rows[i]["Description"].ToString();
li.Value = ds.Tables[0].Rows[i]["AttendanceCode"].ToString();
rbtl.Items.Add(li);
}
}
}
please help me out
Add the null check for radio button list and you will not get error of object reference. Please see the below code
c# code
protected void fillRepeater_onitembound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
sql = "select Description,AttendanceCode from tblattendancecodes";
ds = obj.openDataset(sql);
ListItem li;
RadioButtonList rbtl = (RadioButtonList)e.Item.FindControl("radioatt");
if (rbtl != null)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
li = new ListItem();
li.Text = dt.Rows[i]["ApplicationName"].ToString();
li.Value = dt.Rows[i]["BuildNumber"].ToString();
rbtl.Items.Add(li);
}
}
}
}
I tried the code and it worked for me
Debug your code to find out which line is giving null or is not instantiated correctly and you will get the culprit code.
Related
Inside my repeater control I have a radiobutton list, a dropdown list and a textbox. On selectedIndexChange event of the radiobutton, I am binding dropdown list as my dropdown values should be different for each radiobutton option.
Until this, my functionality is working perfectly. Now I want to autopopulate the textbox value based which will be selected text of dropdown but SelectedIndexChangeEvent of dropdown is calling Radiobutton's selectedIndexChange Event.
Any help on this ?
I have Autopostback set to true of dropdown.
Dropdown selectedIndexChange event is calling radiobutton selectedindexchange Event.
Code
////////////Code Behind File //////////////
Html Part of the code:
<form id="form1" runat="server">
<div>
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table border="1">
<tr>
<th>Name</th>
<th>Country</th>
<th>City</th>
<th>Comments</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblName" Text='<%# Eval("Name") %>' runat="server" />
</td>
<td>
<asp:RadioButtonList ID="rblCountry" runat="server" AutoPostBack="true" OnSelectedIndexChanged="rblCountry_SelectedIndexChanged">
<asp:ListItem Text="United States" Value="US"></asp:ListItem>
<asp:ListItem Text="United Kingdom" Value="UK"></asp:ListItem>
<asp:ListItem Text="Australia" Value="Aus"></asp:ListItem>
</asp:RadioButtonList>
</td>
<td>
<asp:DropDownList ID="ddlCity" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlCity_SelectedIndexChanged">
</asp:DropDownList>
</td>
<td>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</form>
code behind part:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PopulateList();
}
}
private void PopulateList()
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[1] { new DataColumn("Name", typeof(string))});
dt.Rows.Add("John Hammond");
dt.Rows.Add("Mudassar Khan");
dt.Rows.Add("Suzanne Mathews");
dt.Rows.Add("Robert Schidner");
Repeater1.DataSource = dt;
Repeater1.DataBind();
}
protected void rblCountry_SelectedIndexChanged(object sender, EventArgs e)
{
RepeaterItem item = (sender as RadioButtonList).NamingContainer as RepeaterItem;
string countryName = (item.FindControl("rblCountry") as RadioButtonList).Text;
DropDownList ddlCity = item.FindControl("ddlCity") as DropDownList;
TextBox txtCity = item.FindControl("txtCity") as TextBox;
ListItem li;
if (ddlCity != null)
{
ddlCity.Items.Clear();
switch (countryName)
{
case "US":
li = new ListItem() { Text = "Chicago", Value = "Chicago" };
ddlCity.Items.Add(li);
li = new ListItem() { Text = "Washington", Value = "Washington" };
ddlCity.Items.Add(li);
break;
case "UK":
li = new ListItem() { Text = "Manchester", Value = "Manchester" };
ddlCity.Items.Add(li);
li = new ListItem() { Text = "London", Value = "London" };
ddlCity.Items.Add(li);
li = new ListItem() { Text = "Scotland", Value = "Scotland" };
ddlCity.Items.Add(li);
break;
case "Aus":
li = new ListItem() { Text = "Sydney", Value = "Sydney" };
ddlCity.Items.Add(li);
li = new ListItem() { Text = "Melbourne", Value = "Melbourne" };
ddlCity.Items.Add(li);
break;
}
if (ddlCity != null && ddlCity.SelectedItem != null)
txtCity.Text = ddlCity.SelectedItem.Text;
}
}
protected void ddlCity_SelectedIndexChanged(object sender, EventArgs e)
{
RepeaterItem item = (sender as DropDownList).NamingContainer as RepeaterItem;
DropDownList ddlCity = item.FindControl("ddlCity") as DropDownList;
TextBox txtCity = item.FindControl("txtCity") as TextBox;
txtCity.Text = ddlCity.SelectedItem.Text;
}
In my <asp:Repeater></asp:Repeater> - There is one hidden field, textbox and button.
When data will be bound, then hidden filed will get User Id like below code
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>
and ItemDataBound event will be called and in this function, i am getting value from hidden field and concatenating that value as a Id in text box. like below code
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");//1
txt.ID = "txtReplyArea" + hf.Value;//txtReplyArea1
Suppose only one record comes from database and their UserId is 1. Then textbox Id should be "textReplyArea1". From now, all are correct.
I am not sure, it's correct way to giving dynamic Id to repeater control but i think, it's correct.
Problem -
When i click on button and i get a items from repeater and textbox from Id by finding control from repeater then it shows null.
int areaId = int.Parse((sender as Button).CommandArgument);//1
string id="txtReplyArea"+areaId;//txtReplyArea1
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;//tb = null
}
Code of aspx page
<%# Page Title="Messages" Language="C#" MasterPageFile="~/Menu.master" AutoEventWireup="true" CodeFile="Messages.aspx.cs" Inherits="Messages" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div style="width:70%;">
<asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr >
<td>
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>
<asp:TextBox ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>
</td>
</tr>
<tr>
<td style="margin-left:47%;">
<asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True" CommandArgument='<%#Eval("UserId")%>'/>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</asp:Content>
Code of aspx.cs
SqlCommand cmd;
SqlDataReader sdr;
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
String cs = ConfigurationManager.ConnectionStrings["myWebsite"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
cmd = new SqlCommand("select * from ContactMessage", con);
con.Open();
sdr = cmd.ExecuteReader();
repeaterBlog.DataSource = sdr;
repeaterBlog.DataBind();
con.Close();
}
}
}
public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");
txt.ID = "txtReplyArea" + hf.Value;
}
}
protected void btnReplyClicked(object sender, EventArgs e)
{
int areaId = int.Parse((sender as Button).CommandArgument);
string id="txtReplyArea"+areaId;
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;
}
}
}
This worked for me. Notice that I removed EnableViewState from the repeater and added OnItemDatabound event.
<asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server" />
<asp:TextBox ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8"
Visible="false"></asp:TextBox>
</td>
</tr>
<tr>
<td style="margin-left: 47%;">
<asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True"
CommandArgument='<%#Eval("UserId")%>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("UserId");
DataRow dr = dt.NewRow();
dr[0] = 34;
dt.Rows.Add(dr);
repeaterBlog.DataSource = dt;
repeaterBlog.DataBind();
}
public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");
txt.ID = "txtReplyArea" + hf.Value;
}
}
protected void btnReplyClicked(object sender, EventArgs e)
{
int areaId = int.Parse((sender as Button).CommandArgument);
string id = "txtReplyArea" + areaId;
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;
}
}
You can try like this
<asp:TextBox ID='<%# "txtReplyArea" + Convert.ToString(Eval("UserId")%>)' runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>
Structure of my WebPage looks something like:
<asp:Repeter>
<asp:Repeter>
<asp:Repeter>
<asp:DataList>
<asp:Image />
</asp:DataList>
</asp:Repeter>
</asp:Repeter>
</asp:Repeter>
In the output of my Webform, I get all the images in the DataList control. But I want to display just 1st Image from each group.
Here is my code:
.aspx:
<asp:Repeater ID="ParentRepeater" runat="server">
<ItemTemplate>
<table>
<tr>
<td>
<asp:Image ID="imgMinimizeCategory" runat="server" ImageUrl="~/Images/Minimize.jpg" />
</td>
<td>
<asp:Label ID="lblCategory" runat="server" Text='<%# Eval("ProductName")%>' />
</td>
</tr>
<tr>
<td></td>
<td>
<asp:Repeater ID="ChildRepeater" runat="server" DataSource='<%# Eval("Children") %>'>
<ItemTemplate>
<table>
<tr>
<td>
<asp:Image ID="imgMinimizeGroup" runat="server" ImageUrl="~/Images/Minimize.jpg" />
</td>
<td>
<asp:Label ID="lblGroup" runat="server" Text='<%# Eval("ProductName")%>' />
</td>
</tr>
<tr>
<td></td>
<td>
<asp:Repeater ID="ChildrenRepeater" runat="server" DataSource='<%# Eval("Children") %>'>
<ItemTemplate>
<asp:DataList ID="dlProductImages" runat="server" DataSource='<%#Eval("Images") %>' DataKeyField="ImageId"
RepeatColumns="6">
<ItemTemplate>
<asp:Image ID="imageProductImage" runat="server" Height="180px" ImageUrl='<%# Eval("ImageUrl") %>' Width="180px" />
</ItemTemplate>
</asp:DataList>
</ItemTemplate>
</asp:Repeater>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MenuItem SelectedMenuItemInMaster = Session["SelectedMenuItem"] as MenuItem;
ParentRepeater.DataSource = GetProducts(SelectedMenuItemInMaster.Value);
ParentRepeater.DataBind();
}
}
private List<Product> GetProducts(string selectedValue)
{
List<Product> ProductsOfSelectedMenuItem = new List<Product>();
string cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(cs);
SqlDataAdapter da = new SqlDataAdapter("spGetMenuData", con);
DataSet ds = new DataSet();
da.Fill(ds);
foreach (DataRow dr in ds.Tables[0].Rows)
{
if (dr["ParentID"].ToString().Trim() == selectedValue)
{
Product item = new Product();
item.ProductName = dr["ProductName"].ToString();
item.ProductId = (int)dr["ProductId"];
item.ParentId = (int)dr["ParentId"];
foreach (DataRow drChild in ds.Tables[0].Rows)
{
if (drChild["ParentID"].ToString() == dr["ProductId"].ToString())
{
GetChildItems(ds, drChild, item);
}
}
ProductsOfSelectedMenuItem.Add(item);
}
}
SqlDataAdapter daImages = new SqlDataAdapter("Select * from Images", con);
DataSet dsImages = new DataSet();
daImages.Fill(dsImages);
foreach (Product p in ProductsOfSelectedMenuItem)
{
if (p.Children != null)
{
foreach (Product child in p.Children)
{
foreach (Product c in child.Children)
{
foreach (DataRow drImages in dsImages.Tables[0].Rows)
{
if (c.ProductId == (int)drImages["ProductId"])
{
if (c.Images == null)
{
c.Images = new List<Image>();
}
c.Images.Add(new Image() { ImageId = (int)drImages["ImageId"], ImageUrl = drImages["ImageUrl"].ToString(), ProductId = (int)drImages["ProductId"] });
}
}
}
}
}
}
return ProductsOfSelectedMenuItem;
}
private static void GetChildItems(DataSet ds, DataRow dr, Product item)
{
Product childItem = new Product();
childItem.ProductName = dr["ProductName"].ToString();
childItem.ProductId = (int)dr["ProductId"];
childItem.ParentId = (int)dr["ParentId"];
foreach (DataRow drChild in ds.Tables[0].Rows)
{
if (drChild["ParentID"].ToString() == dr["ProductId"].ToString())
{
GetChildItems(ds, drChild, childItem);
}
}
if (item.Children == null)
{
item.Children = new List<Product>();
}
item.Children.Add(childItem);
}
I know, you are thinking that this is a very silly question as I am adding all the images to the collection. But let me explain you. I will use all the images in my next programming step. So, I don't want a collection that does not get images. In short, I want all the images in the collection. When I declare DataSource='<%# Eval("Images")%>' in DataList Tag, I would like to query the collection here. But I don't know how.....
Update:
You can implement a method in code behind that you refer to in the DataSource attribute, and have the method return a subset of the images based on your needs.
DataSource='<%# MyFilteredImageCollection(Eval("Images")) %>'
I am getting an error("input string was not in a correct format") every time I click the lnkUpdate button. Am i missing something? I can't find what's wrong with the codes in the updating event
aspx
<table class="table table-bordered table-hover table-responsive">
<thead>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Received</th>
<th>Remaining</th>
<th>Ordered</th>
<th></th>
</tr>
</thead>
<tbody>
<asp:ListView ID="lvSODetails" runat="server"
onitemcanceling="lvSODetails_ItemCanceling"
onitemediting="lvSODetails_ItemEditing"
onitemupdating="lvSODetails_ItemUpdating" >
<ItemTemplate>
<tr>
<td><%# Eval("ProductID") %></td>
<td><%# Eval("ProductName") %></td>
<td><%# Eval("Received") %></td>
<td><%# Eval("Remaining")%></td>
<td><%# Eval("Quantity") %></td>
<td>
<asp:LinkButton ID="lnkEdit" runat="server"
class="glyphicon glyphicon-pencil" CommandName="Edit" />
</td>
</tr>
</ItemTemplate>
<EditItemTemplate>
<asp:Panel ID="pnlDetails" runat="server" DefaultButton="lnkUpdate">
<tr>
<td><asp:Label ID="lblID" runat="server" Text='<%# Eval("ProductID") %>' /></td>
<td><%# Eval("ProductName") %></td>
<td><asp:TextBox ID="txtQtyReceived" runat="server" /></td>
<td><asp:Label ID="lblRemaining" runat="server" Text='<%# Eval("Remaining") %>' /></td>
<td><%# Eval("Quantity") %></td>
<td>
<asp:LinkButton ID="lnkUpdate" runat="server"
class="glyphicon glyphicon-ok" CommandName="Update" />
<asp:LinkButton ID="lnkCancel" runat="server"
class="glyphicon glyphicon-remove" CommandName="Cancel" />
</td>
</tr>
</asp:Panel>
</EditItemTemplate>
</asp:ListView>
</tbody>
</table>
c# code
protected void lvSODetails_ItemEditing(object sender, ListViewEditEventArgs e)
{
lvSODetails.EditIndex = e.NewEditIndex;
GetInfo();
GetDetails();
}
protected void lvSODetails_ItemCanceling(object sender, ListViewCancelEventArgs e)
{
lvSODetails.EditIndex = -1;
GetInfo();
GetDetails();
}
protected void lvSODetails_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
string ProdID = (lvSODetails.Items[e.ItemIndex].FindControl("lblID") as Label).Text;
string Received = (lvSODetails.Items[e.ItemIndex].FindControl("txtQtyReceived") as TextBox).Text;
string Remaining = (lvSODetails.Items[e.ItemIndex].FindControl("lblRemaining") as Label).Text;
if (int.Parse(Received) < 0) // <~ this is where the code stops (error"input string was not in a correct format")
{
error.Visible = true;
lblError.Text = "Items received must not be lower than zero";
}
else if (int.Parse(Received) >= 0 && int.Parse(Received) <= int.Parse(Remaining))
{
SODetails = (DataTable)Session["sodelivery"];
foreach (DataRow row in SODetails.Rows)
{
if (row["ProductID"].ToString() == ProdID)
{
row["Received"] = Received;
break;
}
}
}
lvSODetails.EditIndex = -1;
GetInfo();
GetDetails();
}
~~~~ Edit ~~~~
listview databinding code
void GetDetails()
{
if (SODetails == null)
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "SELECT sod.ProductID, p.ProductName, sod.SOQtyReceived AS Received, " +
"(sod.SOQtyOrdered - sod.SOQtyReceived) AS Remaining, sod.SOQtyOrdered AS Quantity FROM SODetails AS sod " +
"INNER JOIN Products AS p ON sod.ProductID=p.ProductID WHERE sod.SONo=#SONo";
cmd.Parameters.Add("#SONo", SqlDbType.Int).Value = Request.QueryString["ID"].ToString();
SqlDataAdapter data = new SqlDataAdapter(cmd);
SODetails = new DataTable();
data.Fill(SODetails);
DataRow[] rowList = SODetails.Select();
foreach (DataRow dr in rowList)
{
dr["Received"] = "0";
}
lvSODetails.DataSource = SODetails;
lvSODetails.DataBind();
con.Close();
Session["sodelivery"] = SODetails;
}
else
{
lvSODetails.DataSource = SODetails;
lvSODetails.DataBind();
Session["sodelivery"] = SODetails;
}
}
Your problem isn't that you can't access the TextBox.
Use int.TryParse instead of int.Parse since you are reading user input.
int received;
if (!int.TryParse(Received, out received) || received < 0)
{
error.Visible = true;
lblError.Text = "Items received must not be lower than zero";
}
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);
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;
}
I'll try something like this:
<asp:GridView ID="OrdersGV" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="UserName" />
<asp:TemplateField>
<ItemTemplate>
<asp:ListView ID="NewsLV" runat="server">
<ItemTemplate>
<td id="Td1" runat="server" valign="top" style="width: 30px;">
<asp:Label ID="Label1" runat="server" Text='<%# Eval("RoleName") %>' Visible='<%# Container.DataItemIndex == 0%>'></asp:Label>
<div style="padding: 2px;">
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Eval("IsRoleSelected") %>' />
</div>
</td>
</ItemTemplate>
<LayoutTemplate>
<table id="Table1" runat="server" border="0" style="">
<tr id="itemPlaceholderContainer" runat="server">
<td id="itemPlaceholder" runat="server">
</td>
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>