Wednesday, April 28, 2010

ASP.NET RadioButton “patch”

I previously blogged about a problem regarding radio buttons in ASP.NET. Well, I had hope that .NET 4 would fix this problem, but alas it was not. It turns out that even though you can control client ID’s in ASP.NET 4, you still can’t really control group names. Well, for a project I’m working on, I decided to fix the problem. Here is the code for what I did.


   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Collections.Specialized;
   4:  using System.Linq;
   5:  using System.Reflection;
   6:  using System.Text;
   7:  using System.Web.UI.WebControls;
   8:   
   9:  namespace YourNamespace.Web.UI.WebControls
  10:  {
  11:      public class RadioButton : System.Web.UI.WebControls.RadioButton
  12:      {
  13:          #region Properties
  14:           
  15:          public override string GroupName
  16:          {
  17:              get
  18:              {
  19:                  return base.GroupName;
  20:              }
  21:              set
  22:              {
  23:                  // Setting a private member in the base class that will make the output of the control correct
  24:                  FieldInfo uniqueGroupName = this.GetType().BaseType.GetField("_uniqueGroupName", 
  25:                      BindingFlags.Instance | BindingFlags.NonPublic);
  26:                  uniqueGroupName.SetValue(this, value);
  27:                  base.GroupName = value;
  28:              }
  29:          }
  30:   
  31:          #endregion
  32:      }
  33:  }

I used the .NET Reflector to figure out what is going on in the real RadioButton class. This fix will allow complete control over group names in a radio button so you can start using it in a repeater and other nice controls. Upon seeing this work, I decided to augment the RadioButtonList control to allow a group name to be specified there as well.


   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Reflection;
   5:  using System.Text;
   6:  using System.Web.UI.WebControls;
   7:   
   8:  namespace YourNamespace.Web.UI.WebControls
   9:  {
  10:      public class RadioButtonList : System.Web.UI.WebControls.RadioButtonList
  11:      {
  12:          #region Properties
  13:   
  14:          /// <summary>
  15:          /// The specific group name that each radio button will belong to
  16:          /// </summary>
  17:          public string GroupName
  18:          {
  19:              get
  20:              {
  21:                  string str = (string)this.ViewState["RadioButtonListGroupName"];
  22:                  if (str != null)
  23:                  {
  24:                      return str;
  25:                  }
  26:                  return string.Empty;
  27:              }
  28:              set
  29:              {
  30:                  // Override the repeating control with the new information
  31:                  FieldInfo repeatingControlField = this.GetType().BaseType.GetField("_controlToRepeat",
  32:                      BindingFlags.Instance | BindingFlags.NonPublic);
  33:   
  34:                  System.Web.UI.WebControls.RadioButton oldRepeatingControl = repeatingControlField.GetValue(this) as System.Web.UI.WebControls.RadioButton;
  35:                  if (oldRepeatingControl != null)
  36:                  {
  37:                      this.Controls.Remove(oldRepeatingControl);
  38:                  }
  39:   
  40:                  RadioButton newRepeatingControl = new RadioButton();
  41:                  newRepeatingControl.EnableViewState = false;
  42:                  newRepeatingControl.GroupName = value;
  43:                  this.Controls.Add(newRepeatingControl);
  44:                  newRepeatingControl.AutoPostBack = this.AutoPostBack;
  45:                  newRepeatingControl.CausesValidation = this.CausesValidation;
  46:                  newRepeatingControl.ValidationGroup = this.ValidationGroup;
  47:   
  48:                  repeatingControlField.SetValue(this, newRepeatingControl);
  49:                  this.ViewState["RadioButtonListGroupName"] = value;
  50:              }
  51:          }
  52:   
  53:          #endregion
  54:      }
  55:  }

This uses the RadioButton class that I showed previously. What’s nice about .NET is that if you want to use these controls right away without changing your existing code to can use the tag mapping feature in the web.config. This will basically remap the tags to a different assembly.

No comments:

Post a Comment