Custom RadioButtonList loses value on PostBack
I created a custom RadioButtonList which renders as an unordered list based on a similar code example for a custom CheckBoxList.
But for some reason my selected item isn't saved when performing a postback. The only method I overrided is the Render-method:
[ToolboxData( "<{0}:ULRadioButtonList runat=server></{0}:ULRadioButtonList>" )]
public class ULRadioButtonList : RadioButtonList {
protected override void Render( HtmlTextWriter writer ) {
Controls.Clear();
string input = "<input id={0}{1}{0} name={0}{2}{0} type={0}radio{0} value={0}{3}{0}{4} />";
string label = "<label for={0}{1}{0}>{2}</label>";
string list = "<ul>";
if ( !String.IsNullOrEmpty( CssClass ) ) {
list = "<ul class=\"" + CssClass + "\">";
}
writer.WriteLine( list );
for ( int index = 0; index < Items.Count; index++ ) {
writer.Indent++;
writer.Indent++;
writer.WriteLine( "<li>" );
writer.Indent++;
StringBuilder sbInput = new StringBuilder();
StringBuilder sbLabel = new StringBuilder();
sbInput.AppendFormat(
input,
"\"",
base.ClientID + "_" + index.ToString(),
base.UniqueID,
base.Items[index].Value,
(base.Items[index].Selected ? " checked=\"\"" : "")
);
sbLabel.AppendFormat(
label,
"\"",
b开发者_StackOverflowase.ClientID + "_" + index.ToString(),
base.Items[index].Text
);
writer.WriteLine( sbInput.ToString() );
writer.WriteLine( sbLabel.ToString() );
writer.Indent = 1;
writer.WriteLine( "</li>" );
writer.WriteLine();
writer.Indent = 1;
writer.Indent = 1;
}
writer.WriteLine( "</ul>" );
}
}
Did I forget something? If I use a regular ASP.NET RadioButtonList my selected item is saved after the postback so there is nothing else which is overriding my value; it has something to do with the custom control.
For such approach to work, you must match name
(and id) attributes in your generate markup with that of RadioButtonList
. So obvious issue in your code is the value of name
attribute - it should be appended with the index for each radio button i.e.
...
sbInput.AppendFormat(
input,
"\"",
base.ClientID + "_" + index.ToString(),
base.UniqueID + index.ToString(), // <<< note the change here
base.Items[index].Value,
...
Also instead of "_" in id generation, you should use ClientIdSeparator property.
Finally, I must advice you against such control authoring approach because its inherently brittle i.e. it can break if there is change in how underlying ASP.NET control generates its markup. For example, in ASP.NET, client id generation logic can be configured and so your id generation logic may not work correctly to match the original markup generated by the base control.
精彩评论