I have User Control
<table style="border-width: 0">
<tr>
<td style="vertical-开发者_Python百科align: middle;">
<asp:RadioButton ID="rdOption" runat="server" Text="I m testing"
GroupName="Questions" oncheckedchanged="rdOption_CheckedChanged"
AutoPostBack="True"/>
</td>
<td style="vertical-align: middle; padding-left: 10px">
<asp:TextBox ID="txtOthers" runat="server" CssClass="txtbox" Visible="false"></asp:TextBox>
</td>
</tr>
</table>
protected void Page_Load(object sender, EventArgs e)
{
rdOption.GroupName = "myGroup";
rdOption.Text = Option.OptionDesc;
}
on Survery.aspx I loaded that user control dynamically
foreach (clsOptions option in _CurrentQuestion.Options)
{
UserControls_OptionField ctrl = Page.LoadControl("~/UserControls/OptionField.ascx") as UserControls_OptionField;
ctrl.Option = option;
pnlOption.Controls.Add(ctrl);
}
Problem is that each option have diffrent group name shown below. Thats why options are not working properly and all option can be selected while in MCQs only one option can be selected.
<input id="ContentPlaceHolder1_ctl01_rdOption" type="radio" name="ctl00$ContentPlaceHolder1$ctl01$myGroup" value="rdOption">
<input id="ContentPlaceHolder1_ctl02_rdOption" type="radio" name="ctl00$ContentPlaceHolder1$ctl02$myGroup" value="rdOption">
As all advised, this is by design, and considered a bug later.
The control Joel suggested is so great, except it overrides entire Render logic, so, any enhancement in the framework after this control is written is not used.
So, I suggest replacing the Render()
method in the other control with:
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
using (var stringWriter = new StringWriter())
using (var htmlWriter = new HtmlTextWriter(stringWriter))
{
base.Render(htmlWriter);
var tagText = stringWriter.ToString();
tagText = Regex.Replace(tagText, "name=\"(\\S+)\"", "name=\"" + GroupName + "\"");
writer.Write(tagText);
}
}
The benefit is being able to keep all extra stuff that may come from base rendering.
Please note that you can:
Add another property to the class to make this different render behavior optional based on whether the property is set
Make all the
<asp:RadioButton:
declarations refer to your custom controls without changing them, via web.config:
<system.web> <pages> <tagMapping> <add tagType="System.Web.UI.WebControls.RadioButton" mappedTagType="WebformsLibrary.CustomRadioButton" /> </tagMapping> </pages> </system.web>
Where WebformsLibrary.CustomRadioButton
is the class.
I think that this is a bug that is in ASP.Net since 1.0(awesome, they have forgotten that completely ^^).
You could try following solution that works for a Repeater(or any databound control) but should also work for your dynamic UserControls.
The problem is that ASP.Net renders different unique names for different NamingContainers and therefore the RadioButtons get different GroupNames.
http://weblogs.asp.net/joseguay/archive/2008/07/24/having-radiobuttons-on-a-repeater-or-datalist.aspx
Put this in your HEAD section of your page's:
function SetUniqueRadioButton(nameregex, current)
{
re = new RegExp(nameregex);
for(i = 0; i < document.forms[0].elements.length; i++)
{
elm = document.forms[0].elements[i]
if (elm.type == 'radio')
{
if (re.test(elm.name))
{
elm.checked = false;
}
}
}
current.checked = true;
}
Add the clientside onclick event to the RadioButtons with appropriate parameters:
string script = "SetUniqueRadioButton('rdOption.*myGroup',this)";
rdOption.Attributes.Add("onclick", script);
[not tested]
You need to set the "GroupName" property on each of the RadioButtons to the same thing.
EDIT: If you are using .net 4 then I think using the ClientIDMode property to control the ID's will work. Otherwise, what your are doing is a known issue in asp.net (normally manifested by putting radio buttons in a repeater/listview).
You will need to make your own control and implement the INamingContainer interface to work for your radio's or use a RadioButtonGroup without the usercontrol. I have also seen some solutions that use javascript to enforce the one selection only mode.
Like Tim said, this is a known bug. Here is a usercontrol that inherits from RadioButton, but solves the issue you are having: http://www.codeproject.com/KB/webforms/How_group_RButtons.aspx.
I found this solution to be nicer. It is similar to Tim Schmelter's solution, but I figured that it'd be easier to set the name to what it's meant to be, so that it's what you expect when you use it or look at it, and you don't have to manually set whether every radio button is checked every time one is clicked.
function fixRadioButtons(s, e) {
var re = /^(?:.*\$)?(.*)$/;
for (i = 0; i < document.forms[0].elements.length; i++) {
var elm = document.forms[0].elements[i];
if (elm.type == 'radio') {
var match = re.exec(elm.name);
elm.name = match[1];
}
}
}
Then call the function on postback via JS - reference
// This code runs a function on postback
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(fixRadioButtons);
AND/OR: In the code behind (VB.NET) - reference
ClientScript.RegisterStartupScript(Me.GetType(), "Javascript", "fixRadioButtons(null, null);", True)
Note that if you want it to be run every time, not just on postback, then probably you'll need to use ClientScript.RegisterStartupScript
regardless.
精彩评论