我有用户控制
<table style="border-width: 0">
<tr>
<td style="vertical-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;
}
在Survery.aspx上我动态加载了该用户控件
foreach (clsOptions option in _CurrentQuestion.Options)
{
UserControls_OptionField ctrl = Page.LoadControl("~/UserControls/OptionField.ascx") as UserControls_OptionField;
ctrl.Option = option;
pnlOption.Controls.Add(ctrl);
}
问题是每个选项都有不同的组名,如下所示。这就是为什么选项不能正常工作并且可以选择所有选项,而在MCQ中只能选择一个选项。
<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">
答案 0 :(得分:4)
正如所有人建议的那样,这是设计使然,以后会被视为一个bug。
Joel建议的控件非常棒,除了它会覆盖整个Render逻辑,因此,不会使用写入此控件后框架中的任何增强。
所以,我建议用以下代码替换其他控件中的Render()
方法:
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);
}
}
好处是能够保留可能来自基础渲染的所有额外内容。
请注意,您可以:
在类中添加另一个属性,根据属性是否设置,使这个不同的渲染行为可选
通过web.config使所有<asp:RadioButton:
声明引用您的自定义控件而不更改它们:
<system.web> <pages> <tagMapping> <add tagType="System.Web.UI.WebControls.RadioButton" mappedTagType="WebformsLibrary.CustomRadioButton" /> </tagMapping> </pages> </system.web>
WebformsLibrary.CustomRadioButton
是哪个类。
答案 1 :(得分:3)
我认为这是自1.0以来在ASP.Net中的bug(很棒,他们完全忘记了^^ )。
您可以尝试使用适用于Repeater(或任何数据绑定控件)的解决方案,但也应该适用于动态UserControl。
问题是ASP.Net为不同的NamingContainers呈现不同的唯一名称,因此RadioButtons会获得不同的GroupNames。
将它放在页面的HEAD部分:
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;
}
使用适当的参数将clientide onclick事件添加到RadioButtons:
string script = "SetUniqueRadioButton('rdOption.*myGroup',this)";
rdOption.Attributes.Add("onclick", script);
[未经测试]
答案 2 :(得分:0)
您需要将每个RadioButtons上的“GroupName”属性设置为相同的内容。
编辑:如果你使用.net 4,那么我认为使用ClientIDMode属性来控制ID的工作。否则,你正在做的是asp.net中的已知问题(通常表现为将单选按钮放在转发器/列表视图中)。
您将需要自己控制并实现INamingContainer接口以适用于您的无线电或使用不带用户控件的RadioButtonGroup。我还看到了一些使用javascript来强制执行仅一种选择模式的解决方案。
答案 3 :(得分:0)
答案 4 :(得分:0)
我发现这个解决方案更好。它类似于Tim Schmelter的solution,但我认为将名称设置为它的意图更容易,这样它就是什么您希望在使用它或查看它时,并且您不必手动设置每次单击一个单选按钮是否都被选中。
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];
}
}
}
然后通过JS - reference
在回发上调用该函数// This code runs a function on postback
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(fixRadioButtons);
AND / OR:在后面的代码(VB.NET) - reference
ClientScript.RegisterStartupScript(Me.GetType(), "Javascript", "fixRadioButtons(null, null);", True)
请注意,如果您希望每次都能运行它,而不仅仅是在回发时运行,那么您可能无论如何都需要使用ClientScript.RegisterStartupScript
。