【问题标题】:Set flag based on 3 checkboxes根据 3 个复选框设置标志
【发布时间】:2018-02-25 23:40:13
【问题描述】:

我有三个复选框:

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. 全部

所以我创建了一个枚举:

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

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

【问题讨论】:

    标签: c# .net winforms checkbox refactoring


    【解决方案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;
    }
    

    比你的方法短。

    【讨论】:

      【解决方案2】:

      您可以使用[Flags] 属性标记您的枚举,然后使用按位或组合这些状态。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-16
        • 2015-09-09
        • 2017-08-22
        • 1970-01-01
        • 2011-09-20
        • 1970-01-01
        • 2016-07-30
        • 1970-01-01
        相关资源
        最近更新 更多