mskuratowski
mskuratowski

Reputation: 4124

Set flag based on 3 checkboxes

I have three checkboxes:

System.Windows.Forms.CheckBox cb1;
System.Windows.Forms.CheckBox cb2;
System.Windows.Forms.CheckBox cb3;

All of these checkboxes have the same CheckedChanged event:

this.cb1.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged);
this.cb2.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged);
this.cb3.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged);

I have a flag which I need to check later in my app based on checked checkboxes. So, the possibilities are:

  1. Only cb_1
  2. Only cb_2
  3. Only cb_3
  4. Only cb_1&cb_2
  5. Only cb_1&cb_3
  6. Only cb_2&cb_3
  7. All

So I created an enum:

    public enum LimitCbs
    {
        cb_1,
        cb_2,
        cb_3,
        cb_1_2,
        cb_1_3,
        cb_2_3,
        All,
    }

For now, my logic looks like:

private void cb_CheckedChanged(object sender, EventArgs e)
{
    if (cb1.Checked && !cb2.Checked && !cb3.Checked)
    {
        cfg = LimitCbs.cb_1;
    }

    else if (!cb1.Checked && cb2.Checked && !cb3.Checked)
    {
        cfg = LimitCbs.cb_2;
    }

    else if (!cb1.Checked && !cb2.Checked && cb3.Checked)
    {
        cfg = LimitCbs.cb_3;
    }

    else if (cb1.Checked && cb2.Checked && !cbxExportOnlyManholes.Checked)
    {
        cfg = LimitCbs.cb_1_2;
    }

    else if (cb1.Checked && !cb2.Checked && cb3.Checked)
    {
        cfg = LimitCbs.cb_1_3;
    }

    else if (!cb1.Checked && cb2.Checked && cb3.Checked)
    {
        cfg = LimitCbs.cb_2_3;
    }

    else if (cb1.Checked && cb2.Checked && cb3.Checked)
    {
        cfg = LimitCbs.All;
    }
}

Is there any more fancy way to check all requirements?

Upvotes: 0

Views: 534

Answers (2)

Tetyana Korogoda
Tetyana Korogoda

Reputation: 111

You can mark your enum with the [Flags] attribute, and then combine the states with a bitwise OR.

[Flags]
enum LimitCbs
{ None = 0, First = 1, Second = 2, Third = 4 }

...

var boxesChecked = LimitCbs.None;    

if (cb1.Checked)
    boxesChecked |= LimitCbs.First;
if (cb2.Checked)
    boxesChecked |= LimitCbs.Second;

Upvotes: 1

saidfagan
saidfagan

Reputation: 841

I would represent checkbox states as 3-digits binary number. So if cb1 is checked then my number is 001, if cb2 then 010, if cb1 and cb3 then 101, if all then 111 etc. So every possible combination now has corresponding binary number. Then let's change your enum as follows:

public enum LimitCbs
{
    None = 0, //000
    cb_1 = 1, //001
    cb_2 = 2, //010
    cb_3 = 4, //100
    cb_1_2 = 3, //011
    cb_1_3 = 5, //101
    cb_2_3 = 6, //110
    All = 7, //111
}

Finally, your event listener method will change to this:

private void cb_CheckedChanged(object sender, EventArgs e)
{
    // if checked then "1" else "0"
    String s1 = Convert.ToInt32(cb1.Checked).ToString(); 
    String s2 = Convert.ToInt32(cb2.Checked).ToString();
    String s3 = Convert.ToInt32(cb3.Checked).ToString();
    //concatenate all digits;
    String s = s3 + s2 + s1;
    //convert string in binary to int in decimal
    int i = Convert.ToInt32(s, 2);
    //and finally get enum from int
    cfg = (LimitCbs)i;
}

It is shorter than your method.

Upvotes: 1

Related Questions