views:

802

answers:

1

I have a radio button control adaptor that attempts to render the radio button control with the CSS class as part of the input tag, rather than as a surrounding span.

public class RadioButtonAdapter : WebControlAdapter
{
    protected override void Render(HtmlTextWriter writer)
    {
        RadioButton targetControl = this.Control as RadioButton;

        if (targetControl == null)
        {
            base.Render(writer);

            return;
        }                    

        writer.AddAttribute(HtmlTextWriterAttribute.Id, targetControl.ClientID);
        writer.AddAttribute(HtmlTextWriterAttribute.Type, "radio");        
        writer.AddAttribute(HtmlTextWriterAttribute.Name, targetControl.GroupName); //BUG - should be UniqueGroupName        
        writer.AddAttribute(HtmlTextWriterAttribute.Value, targetControl.ID);
        if (targetControl.CssClass.Length > 0)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Class, targetControl.CssClass);
        }        

        if (targetControl.Page != null)
        {
            targetControl.Page.ClientScript.RegisterForEventValidation(targetControl.GroupName, targetControl.ID);
        }
        if (targetControl.Checked)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Checked, "checked");
        }            
        writer.RenderBeginTag(HtmlTextWriterTag.Input);
        writer.RenderEndTag();

    }
}

Currently, this renders pretty close to what I want, the only difference being the group name attribute (the standard radio button uses the internal value UniqueGroupName, whereas I am using just GroupName. I can't seem to find a way to get UniqueGroupName, and the line below should counter this anyway:

targetControl.Page.ClientScript.RegisterForEventValidation(targetControl.GroupName, targetControl.ID);

Old HTML with standard radio buttons-

<span class="radio">
<input id="ctl00_ctl00_mainContent_RadioButton1" type="radio" value="RadioButton1" name="ctl00$ctl00$mainContent$mygroup"/>
</span>

New rendering-

<input id="ctl00_ctl00_mainContent_RadioButton1" class="radio" type="radio" value="RadioButton1" name="mygroup"/>

The problem is that postback is not working - the RadioButton1.Checked value is always false. Any ideas on how to get the radio button's value in postback?

+2  A: 

The reason postbacks aren't working is because on the return trip the field name doesn't match what ASP.NET was expecting. So, it's not an ideal solution, but you can use reflection to get the UniqueGroupName:

using System.Reflection;

//snip...

RadioButton rdb = this.Control as RadioButton;
string uniqueGroupName = rdb.GetType().GetProperty("UniqueGroupName",
    BindingFlags.Instance | BindingFlags.NonPublic).GetValue(rdb, null) as string;

Or broken into separate lines for clarity:

Type radioButtonType = rdb.GetType(); //or typeof(RadioButton)

//get the internal property
PropertyInfo uniqueGroupProperty = radioButtonType.GetProperty("UniqueGroupName",
    BindingFlags.Instance | BindingFlags.NonPublic);

//get the value of the property on the current RadioButton object
object propertyValue = uniqueGroupProperty.GetValue(rdb, null);

//cast as string
string uniqueGroupName = propertyValue as string;
Rex M
Thanks, worked perfectly.
Spongeboy