WinForms RadioButtonList doesn't exist?

If you just want to group radio buttons, it's enough to put them in a container, then they will act like a group, but if you need data-binding like how a ComboBox or ListBox or CheckedListBox works, you need a RadioButtonList control.

Windows forms doesn't have a built-in RadioButtonList control. You can create your own control by deriving form ListBox and making it owner-draw and draw radio buttons yourself. This is the way which CheckedListBox is created as well.

This way, the control supports data-binding and will benefit from all features of ListBox, including DataSource, SelectedValue, DisplayMember, ValueMember and so on. For example you can simply use it this way:

this.radioButtonList1.DataSource = peopleTable; 
this.radioButtonList1.DisplayMember = "Name"; 
this.radioButtonList1.ValueMember= "Id";

Or for example for an enum, simply this way:

this.radioButtonList1.DataSource = Enum.GetValues(typeof(DayOfWeek)); 

In below image, the second RadioButtonList is disabled by setting Enabled = false;:

enter image description here enter image description here

Also the control supports right to left as well:

enter image description here

It also supports multi column:

enter image description here

RadioButtonList

Here is the source code for control. You can use it like a normal ListBox by adding items or setting data source with/without using data-binding:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
public class RadioButtonList : ListBox
{
    Size s;
    public RadioButtonList()
    {
        this.DrawMode = DrawMode.OwnerDrawFixed;
        using (var g = Graphics.FromHwnd(IntPtr.Zero))
            s = RadioButtonRenderer.GetGlyphSize(
                Graphics.FromHwnd(IntPtr.Zero), RadioButtonState.CheckedNormal);
    }
    protected override void OnDrawItem(DrawItemEventArgs e)
    {

        var text = (Items.Count > 0) ? GetItemText(Items[e.Index]) : Name;
        Rectangle r = e.Bounds; Point p;
        var flags = TextFormatFlags.Default | TextFormatFlags.NoPrefix;
        var selected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
        var state = selected ?
            (Enabled ? RadioButtonState.CheckedNormal : 
                       RadioButtonState.CheckedDisabled) :
            (Enabled ? RadioButtonState.UncheckedNormal : 
                       RadioButtonState.UncheckedDisabled);
        if (RightToLeft == System.Windows.Forms.RightToLeft.Yes)
        {
            p = new Point(r.Right - r.Height + (ItemHeight - s.Width) / 2,
                r.Top + (ItemHeight - s.Height) / 2);
            r = new Rectangle(r.Left, r.Top, r.Width - r.Height, r.Height);
            flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
        }
        else
        {
            p = new Point(r.Left + (ItemHeight - s.Width) / 2,
            r.Top + (ItemHeight - s.Height) / 2);
            r = new Rectangle(r.Left + r.Height, r.Top, r.Width - r.Height, r.Height);
        }
        var bc = selected ? (Enabled ? SystemColors.Highlight : 
            SystemColors.InactiveBorder) : BackColor;
        var fc = selected ? (Enabled ? SystemColors.HighlightText : 
            SystemColors.GrayText) : ForeColor;
        using (var b = new SolidBrush(bc))
            e.Graphics.FillRectangle(b, e.Bounds);
        RadioButtonRenderer.DrawRadioButton(e.Graphics, p, state);
        TextRenderer.DrawText(e.Graphics, text, Font, r, fc, bc, flags);
        e.DrawFocusRectangle();
        base.OnDrawItem(e);
    }
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override SelectionMode SelectionMode
    {
        get { return System.Windows.Forms.SelectionMode.One; }
        set { }
    }
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override int ItemHeight
    {
        get { return (this.Font.Height + 2); }
        set { }
    }
    [EditorBrowsable(EditorBrowsableState.Never), Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override DrawMode DrawMode
    {
        get { return base.DrawMode; }
        set { base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; }
    }
}

Apparently not.

You can group three RadioButtons together using a GroupBox or a Panel as is done here.


The simple fact that several radio buttons are in the same container makes them mutually exclusive, you don't have to code this behavior yourself. Just put them in a Panel or GroupBox as suggested by Matthew