How do I group Windows Form radio buttons?
Asked Answered
M

9

358

How can I group the radio buttons in Windows Form application (a lot like ASP.NET's radiobuttonlist!)?

So I can switch between each case chosen from the options.

Misogamy answered 1/2, 2010 at 16:27 Comment(2)
You can take a look at Windows Forms RadioButtonListIrreverence
See screenshot: https://mcmap.net/q/92678/-how-do-i-group-windows-form-radio-buttonsErosive
C
481

Put all radio buttons for a group in a container object like a Panel or a GroupBox. That will automatically group them together in Windows Forms.

Children answered 1/2, 2010 at 16:30 Comment(4)
@mohammadsadeghsaati The question was about the Windows Forms RadioButton, it does not expose a GroupName property.Encrimson
@Encrimson what if I cant add group boxes and panels due to any problem let say I don't have much space on my form. Then?Longs
@MuhammadSaqib it's impossible because panels can be zero-sized. I mean panels with invisible borders and without margins are the same as plain form. Just use right panel - TableLayoutPanel if you should group in table etcChangeover
This no longer seems to be the case. I created a test project that has nothing except a Form with a Panel and 2 Radiobuttons inside. Clicking the unchecked one does nothing. I have confirmed that they are inside the Panel because deleting the Panel also deletes the Radiobuttons.Loper
S
44

Look at placing your radio buttons in a GroupBox.

Shalondashalt answered 1/2, 2010 at 16:29 Comment(1)
GroupBox is totally unrelated to radio buttons. Any container will do.Mattias
H
37

You should place all the radio buttons of the group inside the same container such as a GroupBox or Panel.

Hooten answered 1/2, 2010 at 16:30 Comment(1)
It gets complicated when you've got layers of nested panels, such as when you are trying to do something that looks like this. The radio buttons conflict with their parents.Analysand
F
27

I like the concept of grouping RadioButtons in WPF. There is a property GroupName that specifies which RadioButton controls are mutually exclusive (http://msdn.microsoft.com/de-de/library/system.windows.controls.radiobutton.aspx).

So I wrote a derived class for WinForms that supports this feature:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Windows.Forms.VisualStyles;
using System.Drawing;
using System.ComponentModel;

namespace Use.your.own
{
    public class AdvancedRadioButton : CheckBox
    {
        public enum Level { Parent, Form };

        [Category("AdvancedRadioButton"),
        Description("Gets or sets the level that specifies which RadioButton controls are affected."),
        DefaultValue(Level.Parent)]
        public Level GroupNameLevel { get; set; }

        [Category("AdvancedRadioButton"),
        Description("Gets or sets the name that specifies which RadioButton controls are mutually exclusive.")]
        public string GroupName { get; set; }

        protected override void OnCheckedChanged(EventArgs e)
        {
            base.OnCheckedChanged(e);

            if (Checked)
            {
                var arbControls = (dynamic)null;
                switch (GroupNameLevel)
                {
                    case Level.Parent:
                        if (this.Parent != null)
                            arbControls = GetAll(this.Parent, typeof(AdvancedRadioButton));
                        break;
                    case Level.Form:
                        Form form = this.FindForm();
                        if (form != null)
                            arbControls = GetAll(this.FindForm(), typeof(AdvancedRadioButton));
                        break;
                }
                if (arbControls != null)
                    foreach (Control control in arbControls)
                        if (control != this &&
                            (control as AdvancedRadioButton).GroupName == this.GroupName)
                            (control as AdvancedRadioButton).Checked = false;
            }
        }

        protected override void OnClick(EventArgs e)
        {
            if (!Checked)
                base.OnClick(e);
        }

        protected override void OnPaint(PaintEventArgs pevent)
        {
            CheckBoxRenderer.DrawParentBackground(pevent.Graphics, pevent.ClipRectangle, this);

            RadioButtonState radioButtonState;
            if (Checked)
            {
                radioButtonState = RadioButtonState.CheckedNormal;
                if (Focused)
                    radioButtonState = RadioButtonState.CheckedHot;
                if (!Enabled)
                    radioButtonState = RadioButtonState.CheckedDisabled;
            }
            else
            {
                radioButtonState = RadioButtonState.UncheckedNormal;
                if (Focused)
                    radioButtonState = RadioButtonState.UncheckedHot;
                if (!Enabled)
                    radioButtonState = RadioButtonState.UncheckedDisabled;
            }

            Size glyphSize = RadioButtonRenderer.GetGlyphSize(pevent.Graphics, radioButtonState);
            Rectangle rect = pevent.ClipRectangle;
            rect.Width -= glyphSize.Width;
            rect.Location = new Point(rect.Left + glyphSize.Width, rect.Top);

            RadioButtonRenderer.DrawRadioButton(pevent.Graphics, new System.Drawing.Point(0, rect.Height / 2 - glyphSize.Height / 2), rect, this.Text, this.Font, this.Focused, radioButtonState);
        }

        private IEnumerable<Control> GetAll(Control control, Type type)
        {
            var controls = control.Controls.Cast<Control>();

            return controls.SelectMany(ctrl => GetAll(ctrl, type))
                                      .Concat(controls)
                                      .Where(c => c.GetType() == type);
        }
    }
}
Francoisefrancolin answered 26/4, 2013 at 14:53 Comment(3)
This came in handy for me in a situation where I needed RadioButtons in a group inside a TableLayoutPanel - thank you!Usquebaugh
I'm trying to use this class for one of my own forms, but having trouble getting the control to display on top of a group box (as if it is the group box's title). It is meant to serve as the top-level radio button (id est, the group for this radio button is a panel at the root of the form and the group box is a sibling). Is there any example code on how to use this class to achieve that?Analysand
I would write IEnumerable<Control> arbControls = null; instead of using dynamic. The var masks it even more, and that's why I normally use only explicit types in my code. Otherwise, very good job, and thanks a lot for sharing this! +1Arndt
C
14

Radio button without panel

public class RadioButton2 : RadioButton
{
   public string GroupName { get; set; }
}

private void RadioButton2_Clicked(object sender, EventArgs e)
{
    RadioButton2 rb = (sender as RadioButton2);

    if (!rb.Checked)
    {
       foreach (var c in Controls)
       {
           if (c is RadioButton2 && (c as RadioButton2).GroupName == rb.GroupName)
           {
              (c as RadioButton2).Checked = false;
           }
       }

       rb.Checked = true;
    }
}

private void Form1_Load(object sender, EventArgs e)
{
    //a group
    RadioButton2 rb1 = new RadioButton2();
    rb1.Text = "radio1";
    rb1.AutoSize = true;
    rb1.AutoCheck = false;
    rb1.Top = 50;
    rb1.Left = 50;
    rb1.GroupName = "a";
    rb1.Click += RadioButton2_Clicked;
    Controls.Add(rb1);

    RadioButton2 rb2 = new RadioButton2();
    rb2.Text = "radio2";
    rb2.AutoSize = true;
    rb2.AutoCheck = false;
    rb2.Top = 50;
    rb2.Left = 100;
    rb2.GroupName = "a";
    rb2.Click += RadioButton2_Clicked;
    Controls.Add(rb2);

    //b group
    RadioButton2 rb3 = new RadioButton2();
    rb3.Text = "radio3";
    rb3.AutoSize = true;
    rb3.AutoCheck = false;
    rb3.Top = 80;
    rb3.Left = 50;
    rb3.GroupName = "b";
    rb3.Click += RadioButton2_Clicked;
    Controls.Add(rb3);

    RadioButton2 rb4 = new RadioButton2();
    rb4.Text = "radio4";
    rb4.AutoSize = true;
    rb4.AutoCheck = false;
    rb4.Top = 80;
    rb4.Left = 100;
    rb4.GroupName = "b";
    rb4.Click += RadioButton2_Clicked;
    Controls.Add(rb4);
}
Changeup answered 12/8, 2014 at 0:16 Comment(0)
E
13

Put radio buttons inside GroupBox (or other panel)

enter image description here

Erosive answered 26/9, 2017 at 10:44 Comment(0)
C
7

All radio buttons inside of a share container are in the same group by default. Means, if you check one of them - others will be unchecked. If you want to create independent groups of radio buttons, you must situate them into different containers such as Group Box, or control their Checked state through code behind.

Clitoris answered 11/4, 2018 at 5:53 Comment(0)
M
5

GroupBox is better.But not only group box, even you can use Panels (System.Windows.Forms.Panel).

  • That is very usefully when you are designing Internet Protocol version 4 setting dialog.(Check it with your pc(windows),then you can understand the behavior)
Malcom answered 7/3, 2013 at 4:1 Comment(0)
S
3

If you cannot put them into one container, then you have to write code to change checked state of each RadioButton:

private void rbDataSourceFile_CheckedChanged(object sender, EventArgs e)
{
    rbDataSourceNet.Checked = !rbDataSourceFile.Checked;
}

private void rbDataSourceNet_CheckedChanged(object sender, EventArgs e)
{
  rbDataSourceFile.Checked = !rbDataSourceNet.Checked;
}
Scherzo answered 24/6, 2016 at 13:30 Comment(1)
This will put you into an infinite loop,,,Murder

© 2022 - 2024 — McMap. All rights reserved.