1

I have one requirement to add three check box in a group box, and check-box must react as radio button i.e., 1. one can check only one check-box at a time. 2. when user goes to check another check box, previous one automatically should be unchecked. I also know that this is not a good approach to do this, and it's really confusing to non-technical or technical user but I also want to learn something new in this.

I went through lots of sites, but I didn't get any satisfactory solution. I hope I will get good one from you.

Moreover, There are simple three check box to indicate three things for selection respectively and one text box. If one checks anyone things then texbox shows the selected thing.

For example:- Check-box show C#,ASP.NET and MVC respectively. If one select C# then text-box must show C#.

Thanks... With Thanks and Regards, Ravindra.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398

5 Answers5

1

You can use radio button for this functionality. Image

Tharif
  • 13,794
  • 9
  • 55
  • 77
1

I'd do it like this, assuming you use winforms:

public partial class Form1 : Form
{
    private bool ignoreEvents = false;

    public Form1()
    {
        InitializeComponent();

        //set this handler to the events of all 3 checkboxes
        checkBox1.CheckedChanged += radioCheckboxes_CheckedChanged;
        checkBox2.CheckedChanged += radioCheckboxes_CheckedChanged;
        checkBox3.CheckedChanged += radioCheckboxes_CheckedChanged;
    }

    private void radioCheckboxes_CheckedChanged(object sender, EventArgs e)
    {
        if (!ignoreEvents)
        {
            ignoreEvents = true; // otherwise the other checkboxes would react when i set the state programmatically
            CheckBox current = sender as CheckBox;
            if (current == checkBox1)
            {
                checkBox2.Checked = false;
                checkBox3.Checked = false;
            }
            else if (current == checkBox2)
            {
                checkBox1.Checked = false;
                checkBox3.Checked = false;
            }
            else
            {
                checkBox1.Checked = false;
                checkBox2.Checked = false;
            }
            ignoreEvents = false;
        }
    }
}

With WPF I'd just use a style for a radiobutton so that it looks like a checkbox...

Florian Schmidinger
  • 4,682
  • 2
  • 16
  • 28
  • Sir by this, I think you are saying to format radio button into check box, but my question is , why can't we apply code into check box and in-turns this, it will give more practical approach for newbie in programming. – Ravindra Bisht Mar 17 '15 at 06:33
  • I am using c# on windows form application . – Ravindra Bisht Mar 17 '15 at 06:55
  • @RavindraBisht you have 4 possibilities... either use the code above or use a mediator pattern (google this) or create your own control (You could inherit from RadioButton and override how it's drawn, this is not a really easy task). And last but not least use radiobuttons as they are just like utility shows. If theres not a strict requirement that your radio buttons have to look like checkboxes then i'd use the last approach because if you have multiple choice and single answer it's common practice to use radio buttons and not checkboxes.... – Florian Schmidinger Mar 17 '15 at 07:26
  • @RavindraBisht on the contrairy users will get confused by unexpected behavior of your UI – Florian Schmidinger Mar 17 '15 at 07:27
  • @RavindraBisht also consider using a combobox... it consumes less space and is also common practice – Florian Schmidinger Mar 17 '15 at 07:31
  • I know sir that this a bad practice to use check box instead of radio button, and combo box is a very efficient in this . But I just want to learn how to do that. I wanna boost my knowledge in this. That's all. – Ravindra Bisht Mar 17 '15 at 08:35
  • @RavindraBisht consider the other possibilities i mentioned above then =) – Florian Schmidinger Mar 17 '15 at 08:40
1

you can simply use another task like timer that updates every 50ms , so as to disable the check boxes you want to disable there , in your "checked changed event" only flag the controls , like for checkbox1 = flagdcheckbx = 1 ; and so on.

private async Task writeTimer()
{
   if(ignoreEvents == true)
   {
    ignoreEvents = false;
    switch(flagdcheckbx)
    {
     case 1:
         checkBox2.Checked = false;
         checkBox3.Checked = false;
       break;
     case 2:
         checkBox1.Checked = false;
         checkBox3.Checked = false;
       break;
     case 3:
         checkBox1.Checked = false;
         checkBox2.Checked = false;
       break;
    }
  }
}

private void radioCheckboxes_CheckedChanged(object sender, EventArgs e)
{
    CheckBox current = sender as CheckBox;
    if (current == checkBox1)
    {
        if (current.checked)
        {
             ignoreEvents = true; 
             flagdcheckbx=1;
        }
    }
    else if (current == checkBox2)
    {
        if (current.checked) // it should happen only when checked
        {
             ignoreEvents = true; 
             flagdcheckbx=2;
        }
    }
    else
    {
        if (current.checked)
        {
             ignoreEvents = true; 
             flagdcheckbx=3;
        }
    }
}
yonas mekonen
  • 51
  • 1
  • 7
0

I assume you know how to group RadioButton controls inside a container and you just look for the CheckBox appearance for your radio button groups.

As an option you can modify the RadioButtonList that I've shared in [this post] and add the CheckBox appearance to it. In the following picture you can see two RadioButtonList control, one with CheckBox appearance and the other with RadioButton appearance:

enter image description here

radioButtonList1.DataSource = Enum.GetValues(typeof(DayOfWeek));
radioButtonList1.Appearance = RadioButtonListAppearance.CheckBox;

radioButtonList2.DataSource = Enum.GetValues(typeof(DayOfWeek));

Here is the modified version of code to add Appearance property:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
public class RadioButtonList : ListBox
{
    RadioButtonListAppearance appearance = RadioButtonListAppearance.RadioButton;
    public RadioButtonListAppearance Appearance
    {
        get { return appearance; }
        set { appearance = value; Invalidate(); }
    }
    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);

        if (appearance == RadioButtonListAppearance.RadioButton)
        {
            RadioButtonRenderer.DrawRadioButton(e.Graphics, p, state);
        }
        else if (appearance == RadioButtonListAppearance.CheckBox)
        {
            CheckBoxRenderer.DrawCheckBox(e.Graphics, p, (CheckBoxState)state);
        }
        else
        {
            throw new InvalidOperationException("Appearance is invalid.");
        }
        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; }
    }
}
public enum RadioButtonListAppearance
{
    RadioButton,
    CheckBox
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
0

Assuming you have a few CheckBox controls in a container like a GroupBox, In the load event of your form:

  • Find all CheckBox controls of the container
  • Set AutoCheck property of the CheckBox controls to false
  • Handle Click event of the CheckBox controls and in the event handler, set Checked property of clicked element to true and for rest, set it to false

enter image description here

Here is the code:

private void Form1_Load(object sender, EventArgs e)
{
    var all = groupBox1.Controls.OfType<CheckBox>().ToList();
    foreach (CheckBox c in all)
    {
        c.AutoCheck = false;
        c.Click += (obj, args) =>
        {
            var ThisCheckBox = (CheckBox)obj;
            foreach( CheckBox cc in all.Except(new[] { ThisCheckBox  }))
                cc.Checked = false;
            ThisCheckBox.Checked = true;
        };
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398