根据3个复选框设置标志

时间:2018-02-07 06:25:10

标签: c# .net winforms checkbox refactoring

我有三个复选框:

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

所有这些复选框都具有相同的CheckedChanged事件:

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);

我有一个标志,我需要根据选中的复选框稍后在我的应用中查看。 所以,可能性是:

  1. 仅限cb_1
  2. 仅限cb_2
  3. 仅限cb_3
  4. 仅限cb_1& cb_2
  5. 仅限cb_1& cb_3
  6. 仅限cb_2& cb_3
  7. 所有
  8. 所以我创建了一个枚举:

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

    目前,我的逻辑看起来像是:

    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;
        }
    }
    

    有没有更奇特的方法来检查所有要求?

2 个答案:

答案 0 :(得分:1)

我将复选框状态表示为3位二进制数。因此,如果选中cb1,则我的号码为001,如果cb2为010,则cb1和cb3为101,如果为111等等,那么现在每个可能的组合有相应的二进制数。 然后让我们改变你的枚举如下:

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
}

最后,您的事件侦听器方法将更改为:

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;
}

它比你的方法短。

答案 1 :(得分:0)

您可以使用[Flags]属性标记枚举,然后将状态与按位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;