Click here to Skip to main content
Click here to Skip to main content

How to group RadioButtons

By , 11 Aug 2004
 

Introduction to the problem

'Where is the problem? Haven't you heard about GroupName property?' - you can ask me. Of course, you are right! But...

Let's take an ordinary DataGrid, add a TemplateColumn to its Columns collection, and place a RadioButton control within this column (it can be useful when you would like to provide the user with selection from the DataGrid items). See the code below:

<!-- Countries for selection -->
<asp:DataGrid id="countriesGrid" runat="server" 
         DataKeyField="ID" AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateColumn>
            <ItemTemplate>
                <!-- 
                Draw attention at this control. 
                We would like to use radio-buttons to
                select single country from the list.
                -->
                <asp:RadioButton id="selectRadioButton" 
                    runat="server" GroupName="country" />
            </ItemTemplate>
        </asp:TemplateColumn>
        <asp:BoundColumn DataField="Country" HeaderText="Country" 
                                  HeaderStyle-Font-Bold="True" />
        <asp:BoundColumn DataField="Capital" HeaderText="Capital" 
                                  HeaderStyle-Font-Bold="True" />
    </Columns>
</asp:DataGrid>

Now, bind to the DataGrid some data and run your ASP.NET application. Try to click at the radio buttons in the Countries list. You can select one country!... and another one... and another... Hmm-m! Didn't we really want to get this effect?

Where is a mistake? We have specified GroupName for the RadioButtons to treat them as from the single group, haven't we? Look at the piece of HTML code that has been generated from our web form. You will see something like this:

<!-- Countries for selection -->
<table cellspacing="0" rules="all" border="1" id="countriesGrid" 
                              style="border-collapse:collapse;">
    <tr>
        <td> </td>
        <td style="font-weight:bold;">Country</td>
        <td style="font-weight:bold;">Capital</td>
    </tr>
    <tr>
        <td><input id="countriesGrid__ctl2_selectRadioButton" 
             type="radio" name="countriesGrid:_ctl2:country" 
             value="selectRadioButton" /></td>
        <td>USA</td>
        <td>Washington</td>
    </tr>
    <tr>
        <td><input id="countriesGrid__ctl3_selectRadioButton" 
             type="radio" name="countriesGrid:_ctl3:country" 
             value="selectRadioButton" /></td>
        <td>Canada</td>
        <td>Ottawa</td>
    </tr>
    <!-- etc. -->

The 'name' attributes of the radio-buttons are different. Why? Here is the answer.

When rendering RadioButton control, ASP.NET uses concatenation of GroupName and UniqueID for the value of 'name' attribute. So, this attribute depends on the UniqueID of the control which depends on the owner's UniqueID etc. It is the standard solution of ASP.NET to avoid naming collisions. As the value of the 'name' attribute of the <input type="radio" /> is used for identification of postback data of the radio-button group when the from is submitting, ASP.NET developers decided to isolate radio-button groups within the bounds of the single owner control (i.e., any two radio-buttons from the same group can not have different direct owners), otherwise it can occur that you will use two third party controls that both contain radio-button groups with the same GroupName - in this case, all radio-buttons will be treated as from the single group and that will bring undesirable behavior.

Now you have understood the cause of error, but how to implement the feature we want? In the next section, I'll provide you the solution.

Solution of the problem

To solve the problem I have stated above, I've created a new GroupRadioButton web control derived from the RadioButton.

In this control, I have changed the rendering method so that 'name' attribute of the resulting HTML radio-button now depends on the GroupName only.

Another one modification is postback data handling (IPostBackDataHandler interface has been overridden).

Other functionality of the GroupRadioButton is equivalent to RadioButton.

See the source code of the GroupRadioButton for details.

Using the code

Now, let's modify the initial form. Use the following script for the Countries list:

<%@ Register TagPrefix="vs" Namespace="Vladsm.Web.UI.WebControls" 
                                          Assembly="GroupRadioButton" %>
...
<!-- Countries for selection -->
<asp:DataGrid id="countriesGrid" runat="server" DataKeyField="ID" 
                                     AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateColumn>
            <ItemTemplate>
                <vs:GroupRadioButton id="selectRadioButton" 
                runat="server" GroupName="country" />
            </ItemTemplate>
        </asp:TemplateColumn>
        <asp:BoundColumn DataField="Country" HeaderText="Country" 
                                  HeaderStyle-Font-Bold="True" />
        <asp:BoundColumn DataField="Capital" HeaderText="Capital" 
                                  HeaderStyle-Font-Bold="True" />
    </Columns>
</asp:DataGrid>

Add reference to the GroupRadioButton assembly, bind data for the countriesGrid, and execute this form. You will find that all radio-buttons are in the single group (i.e., user can check only one of them).

It remained only to show how to determine which of the countries have been selected:

using Vladsm.Web.UI.WebControls;
...
private void selectButton_Click(object sender, System.EventArgs e)
{
    // for each grid items...
    foreach(DataGridItem dgItem in countriesGrid.Items)
    {
        // get GroupRadioButton object...
        GroupRadioButton selectRadioButton = 
            dgItem.FindControl("selectRadioButton") as GroupRadioButton;

        // if it is checked (current item is selected)...
        if(selectRadioButton != null && selectRadioButton.Checked)
        {
            // sample data that was boud to the countriesGrid
            DataTable dataSource = DataSource.CreateSampleDataSource();

            // get country corresponding to the current item...
            DataRow row = 
              dataSource.Rows.Find(countriesGrid.DataKeys[dgItem.ItemIndex]);

            // ...and show selected country information
            selectedCountryInfo.Text = 
                String.Format("Selected country: {0}, Capital: {1}", 
                row["Country"], row["Capital"]);

            return;
        }
    }

    // there are no selected countries
    selectedCountryInfo.Text = String.Empty;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Vladimir Smirnov
Web Developer
Russian Federation Russian Federation
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
BugText Label PinmemberFabio Solariwebster25-Jan-13 13:55 
Hi Vladimir!
 
Congratulations for help! I would like about the Text Label of RadioButton.
 
rd.Text = ((QuestaoResposta)e.Item.DataItem).Titulo; 
 
But on rendering screen noop the text Frown | :(
 
Tks!!!!
Fábio Oliveira
Hello folks...

QuestionPlz help me Pinmembersoft.rajasekaran27-Dec-12 17:37 
Sir i am beginner, so plz give step by step approach plz.
 
i am confused
QuestionCSS class not present Pinmemberkarlitr0s11-May-12 1:10 
Hi!
 
Thanks very much for submitting this really mega-handy bit of code, but I couldn't help but notice that there are two things missing.
 
There's a deprecated reference:
 
onClick += Page.GetPostBackClientEvent(this, String.Empty);
 
That needs replacing with:
 
onClick += Page.ClientScript.GetPostBackEventReference(this, String.Empty);
 
Also, the CSS class property is missing. I just popped this line into the RenderInputTag method:
 
htw.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
 
That's done the trick!
 
Thanks again!
 
Karl Alesbury
Questionthe simplest code ..which serves the purpose PinmemberBilal Mustafa Fazlani9-May-12 21:21 
the simplest code ..which serves the purpose
 
namespace CustomControl
{
    public class GroupRadioButton : RadioButton
    {
        public GroupRadioButton()
            : base()
        { }
 
        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(new GroupedRadioButtonTextWriter(writer,this.GroupName));
        }
    }
 
    public class GroupedRadioButtonTextWriter : HtmlTextWriter
    {
        private string groupName;
 
        public GroupedRadioButtonTextWriter(HtmlTextWriter baseWriter, string groupName) : base(baseWriter)
        {
            this.groupName = groupName;
        }
 
        public override void AddAttribute(HtmlTextWriterAttribute key, string value)
        {
            if (key == HtmlTextWriterAttribute.Name)
            {
                base.AddAttribute(key, this.groupName);
            }
            else
            {
                base.AddAttribute(key, value);
            }
        }
    }
}
Bilal Fazlani

QuestionPossible bug? PinmemberGavin Roberts26-Nov-11 11:02 
Hi all,
 
I've just tried using this on a repeater and the LoadPostData failed to find the correct value...
bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            bool result = false;
            string value = postCollection[GroupName];
            if ((value != null) && (value == Value))
            {
                if (!Checked)
                {
                    Checked = true;
                    result = true;
                }
            }
            else
            {
                if (Checked)
                    Checked = false;
            }
            return result;
        }
 
the value returned from the post collection was correct, but the value property was prepending the UniqueID property to it, meaning it never matched.
 
After debugging, I found that postDataKey was the same as the UniqueID, so I changed my code to
 
bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            bool result = false;
            string value = postCollection[GroupName];
            if ((value != null) && (postDataKey + "_" + value == Value))
            {
                if (!Checked)
                {
                    Checked = true;
                    result = true;
                }
            }
            else
            {
                if (Checked)
                    Checked = false;
            }
            return result;
        }
 
And now it works Wink | ;)
GeneralThanks! PinmemberM.AsimSiddiqui15-Jun-11 4:23 
Thanks Working fine for me
GeneralBetter implementation PinmemberMartin Zarate27-Apr-11 7:49 
I've been meaning to write a new article on this, but here's a quick stub ofa better implementation:
 
1) Gut out all the code except for the IPostBackDataHandler_LoadPostData and the Value property. This ensures the proper persistence of the check state despite the name changing.
2) Override the Render method with the following one:
 
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            Dim fixingWriter As New GroupedRadioButtonTextWriter(writer, GroupName)
            MyBase.Render(fixingWriter)
        End Sub
 
and use the following renderer:
 
Friend Class GroupedRadioButtonTextWriter
        Inherits HtmlTextWriter
 
        Private _GroupName As String
 
        Public Sub New(ByVal baseWriter As HtmlTextWriter, ByVal groupName As String)
            MyBase.New(baseWriter)
            _GroupName = groupName
        End Sub
 
        Public Overrides Sub AddAttribute(ByVal key As System.Web.UI.HtmlTextWriterAttribute, ByVal value As String)
            'do not emit any attributes in the ignore list.
            If key <> HtmlTextWriterAttribute.Name Then
                MyBase.AddAttribute(key, value)
            End If
        End Sub
 
        Public Overrides Sub RenderBeginTag(ByVal tagKey As System.Web.UI.HtmlTextWriterTag)
            If (tagKey = HtmlTextWriterTag.Input) Then
                ForceAddAttribute(HtmlTextWriterAttribute.Name, _GroupName)
            End If
 
            MyBase.RenderBeginTag(tagKey)
        End Sub
 
        Public Sub ForceAddAttribute(ByVal key As System.Web.UI.HtmlTextWriterAttribute, ByVal value As String)
            MyBase.AddAttribute(key, value)
        End Sub
    End Class
 
This means you don't have to re-implement all the rendering logic, you're just using the hacked HTMLWriter to fix the "name" bit.
GeneralRe: Better implementation PinmemberChris Clark23-May-11 4:31 
GeneralRe: Better implementation PinmemberTrendyTim29-Nov-11 21:01 
GeneralBetter implementation (C# Version) [modified] Pinmemberflemgrem23-Jan-12 5:02 
GeneralAwesome ! PinmemberZ_KiNGPiN23-Apr-11 21:44 
Awesome 5 star .... Thx a bundle for that .. was pulling my hair out because of that issue
you are my savior Cool | :cool: Thumbs Up | :thumbsup: Thumbs Up | :thumbsup:
GeneralMy vote of 5 Pinmemberccaspers4-Feb-11 10:12 
Great job adding GroupName the way it should have been. Saved me from doing it myself. You rock!
GeneralMy vote of 5 PinmemberEmeka Awagu11-Nov-10 22:55 
It's fantastic and solved a potentially embarrassing problem for me Smile | :)
GeneralFantastic PinmemberMember 46201357-Oct-10 5:34 
Life saver. Works as it should.
 
anyone have checked=false all the time. ensure your repeater, datagrind bind is inside a postback check, other wise the radiobuttons lose their checked status:
 
vb
 
If Not IsPostBack Then
bind repeater/grid
end if
 
sub button_click
check for radiobuttons here
end sub
GeneralMy vote of 5 PinmemberMiroslavBraikov25-Sep-10 22:50 
It works Smile | :)
GeneralMy vote of 3 Pinmembersarodgl11-Aug-10 5:46 
This article is helpful.
GeneralMy vote of 5 PinmemberAndrew Lansdowne3-Aug-10 22:56 
Thank you! Everyone else on the web seems to think the "solution" is to use a Javascript function to change the name.
GeneralMy vote of 3 PinmemberramanarayananAsp29-Jul-10 6:44 
hkh
GeneralYou are IT! PinmemberStevishere27-Apr-10 10:59 
Thanks Vladimir. You just saved me so much grief.
 
I stuck it in my project and it worked, no hassles! Big Grin | :-D
Stevishere
www.Em8s.net

QuestionHow to add Text Property? PinmemberDragothiC4-Mar-10 6:12 
Nice work but it doesn't render out the Text property anymore.
Guess it's easy but I don't know how to do it. Could someone please give me a a little help in C# here?
 
Thanks!
AnswerRe: How to add Text Property? PinmemberChris Clark23-May-11 4:30 
GeneralRe: How to add Text Property? PinmemberTellalca8-Sep-11 2:53 
Generalchecked=false all the time Pinmemberghassan1008-Oct-09 21:59 
hello
i used that new created control , its so smart
but text properity donot work , checked also
text is always nothing , checked is alwayes false
 
my web site is (VB)
 
did i miss any thing
GeneralRe: checked=false all the time Pinmemberlovingit6-Nov-09 10:54 
GeneralRe: checked=false all the time PinmemberMember 46201357-Oct-10 4:55 
Generalcant find control in groupradiobutton (VB.Net Code) Pinmembersarmatvs6-Aug-09 15:07 
Hi below is the code..i kept group radio buttons in gridview
 

<asp:GridView ID="grdbatchnumber" runat="server" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<vs:GroupRadioButton ID="MyRadioBatchnumbers" runat="server" GroupName="rdEmp" ></vs:GroupRadioButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
 
</asp:GridView>
 
--------------------------------------------------
Protected Sub lnkbadge_Click(ByVal sgender As Object, ByVal e As System.EventArgs) Handles lnkbadge.Click
 
XXXXXXX
 

Dim i As Integer
For i = 0 To grdbatchnumber.Rows.Count - 1
 
Dim rd As GroupRadioButton = DirectCast(grdbatchnumber.Rows(i).FindControl("MyRadioBatchnumbers"), GroupRadioButton)
If rd IsNot Nothing AndAlso rd.Checked Then
'If (rd.Checked = True) Then
 
chapterid = ds.Tables(0).Rows(0)(i)
Contestcode = ds.Tables(0).Rows(0)(i + 1)
End If
 
Next i
 

Here when I select the radio button
it always showing rd.checked is false
 
Please help me friends
GeneralThanks Pinmemberhalil ibo10-Jul-09 0:04 
Baba büyüksün...
GeneralThanks! Pinmembereriknsdca29-Mar-09 15:57 
Thanks for the article. Exacly what I needed.
GeneralThanks... I hope MS fixes this in their next release. Good work! PinmemberDire Entity20-Mar-09 14:53 
This had me pulling my hair out. I guess they were too busy working on the Ajax framework to focus on core functionality like having a flipping radio button group inside a listview... Confused | :confused:
 
You're the man.
GeneralThanks a million for your answer Pinmemberaungmyo6-Mar-09 3:10 
Hello Vladimir Smirnov
Thanks you .Another time please explain database connection.
your student
aungaung
GeneralThank you! PinmemberJohn Riston3-Feb-09 5:27 
Vladimir,
 
Thanks so much for this code. I was banging my head against a wall for two days trying to solve the problem. I was trying to solve the problem incorrectly, and this is a much better solution.
 
If you're ever in the DC area, I owe you a beer Smile | :)
Generalcool! but one suggestion..... PinmemberAravind Rajagopal K5-Dec-08 6:56 
Hi Vladimir.....
This is perfect....I just added couple of things to it to make it better...
First of all I converted the code to VB just to make it easy for my fellow project folks....
 
secondly..I added Text property
 
<Bindable(True), Category("Appearance"), DefaultValue("xxxxx")> Property [Text]() As String
Get
Return CType(ViewState("Text"), String)
End Get
Set(ByVal Value As String)
ViewState("Text") = Value
End Set
End Property
 
And changed your RenderInputTag method to include Text property like this
 

htw.RenderBeginTag(HtmlTextWriterTag.Input)
'Before closing it just show the Text here....added by Aravind
htw.Write([Text])
htw.RenderEndTag()
 

Now when I bind the radio button control (see below)....the text gets displayed perfectly....
 
Text='<%# DataBinder.Eval(Container.DataItem, "DrugName") %>'
 
Aravind Rajagopal

GeneralRe: cool! but one suggestion..... PinmemberM.AsimSiddiqui15-Jun-11 4:22 
Generalthanks very much PinmemberGeorge Manjooran5-Nov-08 22:37 
This was truly amazing solution. It saved me atleast a day. Jus googled got this solution.
Once again thanks for this.
Questionhow to give different rows different groupnames? PinmemberThomas19118-Oct-08 23:49 
Thanks for your dll! Smile | :)
 
How do I assign a different string to the GroupName property in every row? When I try to assign in the (nested) repeater, the GroupName property is the same for all rows. I need a group on every row....
GeneralChecked=True PinmemberVivekVashisht3-Oct-08 19:39 
Please help. I want to update database on the basis of selected row.
But can't find the same on button click, button is placed outside the gridview. Both Gridview and Button are inside update panel.
QuestionHow to group RadioButtons Pinmemberjemreal30-Sep-08 15:55 
This is excellent. Thank you!
Generalgreat PinmemberRa...aj13-Sep-08 22:59 
thanks for ur great article
 
RR

QuestionSystem.Security.SecurityException: That assembly does not allow partially trusted callers. PinmemberMember 377988315-Jul-08 23:57 
Hello Guys
 
I have used GroupRadioButton in our website. It works Fine locally.
But when i upload it in the webserver
 
I get the following error message
 
Server Error in '/' Application.
--------------------------------------------------------------------------------
 
Security Exception
Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.
 
Exception Details: System.Security.SecurityException: That assembly does not allow partially trusted callers.
 
Our webserver runs at medium trust.
 
Please help me to solve this issue.
 
Regards
 
Bhushan Pawar
 
emailbhushan@hotmail.com
QuestionGroupRadioButton.Text & GroupRadioButton.ForeColor Doesnt work !?! PinmemberKamiDalton12-Jun-08 3:07 
I DOnt know why but the Text Property and ForeColor Property doesnt work ?
How can we ad these or other propeeties to render Override function?
 
Lord Death †

QuestionCan't get which radiobutton is selected.....always gets checked = false Pinmemberamit_chudasama20-May-08 3:16 
Hi I used GroupRadioButton in repeater control..but whenever i want to get which radio button is clicked when button is clicked on page, it always give me checked = false for every radio button. Please suggest me a solution if have faced this problem and knows solution. Thanks in advance....
RantThanks! Pinmemberagira11-May-08 21:44 
Thanks! Very fine solution of problem!
 
N/A

GeneralExcellent - Thank you PinmemberGeek Queen15-Apr-08 11:58 
I have been struggling with this issue for months and just coding around it as I just hadn't had time to sort it myself. That was so easy and I LOVE being able to use group buttons again.
 
Laugh | :laugh:
 
Cheers, JM
GeneralRe: Excellent - Thank you Pinmembererax dan21-Jul-08 6:16 
Generalproblem is related to radio button list Pinmemberkrishnaveer3-Apr-08 4:21 
friend my problem is that i am taking a radiobutton list in gridview radiobutton list will be select on the basis of data base
how its possible
 
code behaind page
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
If (e.Row.DataItem("isapprove").ToString = "True") Then
Dim radio As RadioButtonList = CType(e.Row.FindControl("RadioButtonList2"), RadioButtonList)
 
Else
 
End If
End If
End Sub
 

html code
 
<asp:TemplateField HeaderText="Activate">
<ItemTemplate>
<asp:RadioButtonList ID="RadioButtonList2" runat="server" AutoPostBack="True" Font-Size="Smaller">
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
</asp:TemplateField>
 
krishna veer singh

GeneralCool. thanks a lot PinmemberMember 98160612-Mar-08 22:04 
Very nice solution
 
f0rza: http://bulenok.com
GeneralThank you PinmemberGlebowski11-Mar-08 1:58 
thank you very much!!!
GeneralNice Pinmemberanzatechnologies13-Mar-08 21:20 
GeneralGreat Thanks Pinmembersstrega20-Feb-08 15:18 
It was very helpfull my project. Thanks for your time...
QuestionGetting error .. Pinmemberumesh0929-Jan-08 23:20 
localy its work fine .. but when i deploy on webserver its giving me error...... on that page which have group radiobotton....
 
The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.
 
Exception Details: System.Security.SecurityException: That assembly does not allow partially trusted callers.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130617.1 | Last Updated 12 Aug 2004
Article Copyright 2004 by Vladimir Smirnov
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid