Introduction
There is one deficiency in ASP.NET RadioButton
Server control. When it is nested to a DataGrid
template, the resultant multiple radio buttons will not work as a group. Vladimir Smirnov has remedied this in his article: How to group RadioButtons. Recently, when I wanted to use his control, it is found that it does not support autopostback event very well. I would like it to behave similar to a command button. After a little bit effort, I made it work, and the following is the changed part. In addition, I also want to share some other methods to achieve the same effect.
Change
When user clicks any radio button, the event will be routed to the RadioButton
class. However, what is missing here is it does not bubble this event to its parent. We need to override onBubbleEvent
function. First of all, we add two properties as follows:
private string commandName;
public string CommandName
{
get{return this.commandName;}
set{this.commandName = value;}
}
public string CommandArgument
{
get
{
object o = this.ViewState["CommandArgument"];
if (o == null)
return null;
else
return System.Convert.ToString(o);
}
set{this.ViewState["CommandArgument"] = value;}
}
CommandArgument
is better to be of type object
. Here, I simply declare it to be string
. CommandName
will not be saved across page postback. If you want to use that way, change it as in CommandArgument
.
The following code is onBubbleEvent
. It bridges RadioButton
and its parent because it will call RaiseBubbleEvent
which will finally invoke event on its parent. Here, only DataGrid
is considered. If you want this RadioButton
to work within DataList
and Repeater
, you can add similar code:
protected override bool OnBubbleEvent(object source, EventArgs args)
{
if ((this.NamingContainer as DataGridItem ) != null)
{
CommandEventArgs cmdarg = new CommandEventArgs(this.commandName,
this.CommandArgument);
DataGridCommandEventArgs e = new
DataGridCommandEventArgs((DataGridItem)this.NamingContainer,
source, cmdarg);
this.RaiseBubbleEvent(this,e);
return true;
}
return false;
}
void IPostBackDataHandler.RaisePostDataChangedEvent()
{
OnCheckedChanged(EventArgs.Empty);
this.OnBubbleEvent(this,System.Web.UI.WebControls.CommandEventArgs.Empty);
}
Now, it is done! When you use it, specify CommandName
and CommandArgument
if necessary and respond to event in DataGrid
's ItemCommand
event handler, the same way as button.
Small Tips
Autopostback event will happen even if it is already selected. I found that ASP.NET RadioButtonList
's autopostback event works also like this. Actually, it is not necessary. So, I made some small changes to correct this. In RenderInputTag
method, add the following code:
onClick += "if(this.selected != null) return true; " +
Page.GetPostBackClientEvent(this, String.Empty);
if(Checked)
htw.AddAttribute(HtmlTextWriterAttribute.Selected,"X");
Here, when a radio button is checked, it will generate an extra attribute selected="X"
. So for checked radio button, the if
condition will evaluate to true
and then return immediately such that postback event will not be invoked.
Three other ways to work around
- In
Page_Load
function, find radio button control in DataGrid
item and add event handler.
- Use non-display button plus client-side radio button. It needs to bind button
ClientID
to radio button's onclick
event.
- Use non-display button plus image mimicking radio button.
For, non-display button and databinding technique, you can reference: Enable DataList Row Highlighting and Click Event PostBack.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.