M
Mark Miller
I have a datagrid where I need to display a list of radiobuttons for each
row. Unfortunatly, RadioButtonList does not meet my requirements because I
need some flexibilty for formatting. So, I added a Repeater control (I tried
Repeater and DataList) to a TemplateColumn to display the list of radio
buttons. Here is an example:
<asp:TemplateColumn>
<ItemTemplate>
<aspataList id="dlPrintFormat" runat="server">
<ItemTemplate>
<table>
<tr>
<td><input type="radio" name="radFormat"
runat="server" value="somevalue"><asp:Label runat="server"
id="lblFormatDescription" text='databoundtext'/></td>
<td><asp:Label runat="server" id="lblPrice"
text='databoundtext'/></td>
</tr>
</table>
</ItemTemplate>
</aspataList>
</ItemTemplate>
</asp:TemplateColumn>
Unfortuanetly the aforementioned bug does not allow a mutually exclusive set
of radio buttons inside of a repeater, datalist or datagrid (for more
details see Q316495). The third thing I tried (and I am really struggling
with this one) is to dynamically create the above layout at runtime in the
ItemDataBound event for the parent DataGrid. I am trying to do this with a
PlaceHolder control. At runtime I create the table, rows, cells,
radiobuttons and labels like this:
public void LoadChildRecords(object Sender, DataGridItemEventArgs e){
if(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType ==
ListItemType.Item){
DataView dvOptions =
((DataRowView)e.Item.DataItem).CreateChildView("ProductOptions");
//the datasource for the datagrid is a dataset w/ 2 tables and one relation
named "ProductOptions"
System.Web.UI.HtmlControls.HtmlTable tbl = new HtmlTable();
tbl.Border = 0;
tbl.CellPadding = 0;
tbl.CellSpacing = 0;
tbl.Width = "100%";
for(int i=0; i<dvOptions.Count; i++){
HtmlTableRow tr = new HtmlTableRow();
HtmlTableCell td = new HtmlTableCell();
HtmlInputRadioButton rad = new HtmlInputRadioButton();
rad.ID = "radFinish";
rad.Name = "radFinish";
rad.Value = dvOptions["ProductSKU"].ToString();
rad.EnableViewState = true;
Label lblFinish = new Label();
lblFinish.Text = dvOptions["FinishDescription"].ToString();
if(i==0){
rad.Checked = true;
}
td.Controls.Add(rad);
td.Controls.Add(lblFinish);
tr.Cells.Add(td);
HtmlTableCell td2 = new HtmlTableCell();
Label lbl = new Label();
lbl.Text =
Double.Parse(dvOptions["MSRP"].ToString()).ToString("C");
td2.Controls.Add(lbl);
tr.Cells.Add(td2);
tbl.Rows.Add(tr);
}
phdPrintFinish = (PlaceHolder)e.Item.FindControl("phdPrintFinish");
phdPrintFinish.Controls.Add(tbl);
}
}
However, those controls are not there at postback. I have read that I must
create them during the Page_OnInit event, but what I don't get is how I
could do that when I don't know how many controls need to be created until I
have the data. Can I create and bind the Datagrid and create the controls
all during the Page_OnInit event? I have considered creating a Server
Control which inherits from RadioButton list and overriding the render
method, but I'm still a bit green in a lot of areas and I don't quite know
where to start if I were to do that.
So is there a more efficient (or simple) way to accomplish this?
Thanks,
Mark
row. Unfortunatly, RadioButtonList does not meet my requirements because I
need some flexibilty for formatting. So, I added a Repeater control (I tried
Repeater and DataList) to a TemplateColumn to display the list of radio
buttons. Here is an example:
<asp:TemplateColumn>
<ItemTemplate>
<aspataList id="dlPrintFormat" runat="server">
<ItemTemplate>
<table>
<tr>
<td><input type="radio" name="radFormat"
runat="server" value="somevalue"><asp:Label runat="server"
id="lblFormatDescription" text='databoundtext'/></td>
<td><asp:Label runat="server" id="lblPrice"
text='databoundtext'/></td>
</tr>
</table>
</ItemTemplate>
</aspataList>
</ItemTemplate>
</asp:TemplateColumn>
Unfortuanetly the aforementioned bug does not allow a mutually exclusive set
of radio buttons inside of a repeater, datalist or datagrid (for more
details see Q316495). The third thing I tried (and I am really struggling
with this one) is to dynamically create the above layout at runtime in the
ItemDataBound event for the parent DataGrid. I am trying to do this with a
PlaceHolder control. At runtime I create the table, rows, cells,
radiobuttons and labels like this:
public void LoadChildRecords(object Sender, DataGridItemEventArgs e){
if(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType ==
ListItemType.Item){
DataView dvOptions =
((DataRowView)e.Item.DataItem).CreateChildView("ProductOptions");
//the datasource for the datagrid is a dataset w/ 2 tables and one relation
named "ProductOptions"
System.Web.UI.HtmlControls.HtmlTable tbl = new HtmlTable();
tbl.Border = 0;
tbl.CellPadding = 0;
tbl.CellSpacing = 0;
tbl.Width = "100%";
for(int i=0; i<dvOptions.Count; i++){
HtmlTableRow tr = new HtmlTableRow();
HtmlTableCell td = new HtmlTableCell();
HtmlInputRadioButton rad = new HtmlInputRadioButton();
rad.ID = "radFinish";
rad.Name = "radFinish";
rad.Value = dvOptions["ProductSKU"].ToString();
rad.EnableViewState = true;
Label lblFinish = new Label();
lblFinish.Text = dvOptions["FinishDescription"].ToString();
if(i==0){
rad.Checked = true;
}
td.Controls.Add(rad);
td.Controls.Add(lblFinish);
tr.Cells.Add(td);
HtmlTableCell td2 = new HtmlTableCell();
Label lbl = new Label();
lbl.Text =
Double.Parse(dvOptions["MSRP"].ToString()).ToString("C");
td2.Controls.Add(lbl);
tr.Cells.Add(td2);
tbl.Rows.Add(tr);
}
phdPrintFinish = (PlaceHolder)e.Item.FindControl("phdPrintFinish");
phdPrintFinish.Controls.Add(tbl);
}
}
However, those controls are not there at postback. I have read that I must
create them during the Page_OnInit event, but what I don't get is how I
could do that when I don't know how many controls need to be created until I
have the data. Can I create and bind the Datagrid and create the controls
all during the Page_OnInit event? I have considered creating a Server
Control which inherits from RadioButton list and overriding the render
method, but I'm still a bit green in a lot of areas and I don't quite know
where to start if I were to do that.
So is there a more efficient (or simple) way to accomplish this?
Thanks,
Mark