Maintaining Checked State On Radio/Checkbox Controls On Post Back
I had a unique problem today. Here's the scenario:
You have a ListView that dynamically loads different ItemTemplates depending on a specific criteria (in my case, a category). You load this user control template into the ItemTemplate and create some radio and checkbox buttons. If you set GroupName on the controls to a group name, .NET will not associate all the different buttons across the templates because they have different naming containers.
I have a dynamically generated form where the user selects from a multitude of options (i.e. each ListViewItemTemplate contains an input control), so this default behavior doesn't work so well. Some might say to scrap the custom ListView and create a composite control that inserts different controls depending on a parameter but then you get into a lot of databinding issues and viewstate tracking issues. I wanted to avoid all of that. Note: If someone has a good way of doing this, please let me know!
Here's what I came up with. It derives from a RadioButton (but a CheckBox would work too) and adds two custom properties, Name and Value, allowing you to specify the value of the input and name of the input. It overrides the Render event and outputs custom HTML depending on if the button was checked on PostBack. It works great!
Public Class CustomRadioButton
Inherits RadioButton
Public Property Name() As String
Get
Dim o As Object = ViewState("Name")
Return If(o Is Nothing, String.Empty, CStr(o))
End Get
Set(ByVal value As String)
ViewState("Name") = value
End Set
End Property
Public Property Value() As String
Get
Dim o As Object = ViewState("Value")
Return If(o Is Nothing, String.Empty, CStr(o))
End Get
Set(ByVal value As String)
ViewState("Value") = value
End Set
End Property
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
If Page.IsPostBack Then
writer.Write(String.Format("<input id='{0}' type='radio' name='{1}' value='{2}' {3} />", ClientID, Name, Value, If(Page.Request.Form(Name) = Value, "checked='checked'", String.Empty)))
Else
writer.Write(String.Format("<input id='{0}' type='radio' name='{1}' value='{2}' />", ClientID, Name, Value))
End If
End Sub
End Class
And in the user control:
<MyControls:CustomRadioButton ID="radButton"
Name='<%#String.Format("rad_group_{0}", Eval("MyGroupId").ToString()) %>'
Value='<%# Eval("MyValue") %>'
runat="server" />
<%-- You can also make it static text. --%>