【问题标题】:Checkbox to (un)check all other checkboxes复选框到(取消选中所有其他复选框
【发布时间】:2013-01-25 16:10:30
【问题描述】:

我创建了一个 Windows 窗体,它(到目前为止)只包含复选框。构造函数接受一个参数:string[] attributes。对于这个 attributes 数组中的每个字符串,我创建一个复选框。

例如:

string[] attributes = {
                          "Black",
                          "Red",
                          "Blue"
                      };
form1 = new MyForm(attributes);
form1.Show();

会像这样创建复选框:

[ ] Black
[ ] Red
[ ] Blue

这很好用。现在我的下一步是创建一个复选框“Check All”,它具有以下行为。我将使用this 来指代我的“全选”复选框

时间:

  • 用户检查this:所有其他复选框都被选中。
  • 用户取消选中this:所有其他复选框均未选中。
  • 所有其他复选框都被手动选中:this 也被选中。
  • 所有复选框都已选中,其中任何一个都未选中:this 也未选中。

我设法完成了上述所有规则,但我遇到了一个问题,我不知道如何解决它:当所有复选框都被选中并且用户取消选中一个复选框时,这意味着我的 "Check全部”复选框 也将被取消选中。现在我的 "Check All" 复选框 未被选中,它会自动调用 uncheck 事件,然后取消选中所有复选框,就好像用户未选中我的 "Check All" 复选框 .

那么当另一个复选框调用取消选中时,有没有办法告诉我的复选框不要运行CheckedChanged

这是我的代码(都是手写的,所以没有使用 Visual Studio 设计师):

using System;
using System.Drawing;
using System.Windows.Forms;

class MyForm
{
    public MyForm(string[] attributes)
    {
        SpawnControls(attributes);
    }

    private CheckBox[] m_attributes;
    private CheckBox m_all;

    private void SpawnControls(string[] attributes)
    {
        CheckBox dummy = new CheckBox();
        int nAttr = attributes.Length;

        m_attributes = new CheckBox[nAttr];
        for (int i = 0; i < nAttr; i++)
        {
            m_attributes[i] = new CheckBox();
            m_attributes[i].Text = attributes[i];
            m_attributes[i].Location = new Point(5, dummy.Height * i);
            m_attributes[i].CheckedChanged += attribute_CheckedChanged;
            Controls.Add(m_attributes[i]);
        }

        m_all = new CheckBox();
        m_all.Text = "Check All";
        m_all.Location = new Point(5, m_attributes[nAttr - 1].Bottom);
        m_all.CheckedChanged += all_CheckedChanged;
        Controls.Add(m_all);
    }

    private void attribute_CheckedChanged(object sender, EventArgs e)
    {
        if (((CheckBox)sender).Checked)
        {
            foreach (CheckBox cb in m_attributes)
            {
                if (cb.Checked == false)
                {
                    return;
                }
            }
            m_all.Checked = true;
        }
        else if (m_all.Checked)
        {
            m_all.Checked = false;
        }
    }

    private void all_CheckedChanged(object sender, EventArgs e)
    {
        if (m_all.Checked)
        {
            foreach (CheckBox cb in m_attributes)
            {
                cb.Checked = true;
            }
        }
        else
        {
            foreach (CheckBox cb in m_attributes)
            {
                cb.Checked = false;
            }
        }
    }
}

【问题讨论】:

    标签: c# winforms checkbox


    【解决方案1】:

    您可以在事件处理程序的开头检查 All_Check 控件是否有焦点,如果没有焦点则退出事件。

    private void all_CheckedChanged(object sender, EventArgs e)
    {
    
        if (!m_all.Focused)
         return ;
    
        if (m_all.Checked)
        {
            foreach (CheckBox cb in m_attributes)
            {
                cb.Checked = true;
            }
        }
        else
        {
            foreach (CheckBox cb in m_attributes)
            {
                cb.Checked = false;
            }
        }
    }
    

    【讨论】:

    • 嗯,另一个不错的解决方案,我也去看看,谢谢:P
    • 最终使用了这个,更干净的 imo,尤其是在 if 语句中添加评论之后:)
    【解决方案2】:

    您可以添加一个布尔成员级变量来标记您的事件处理程序逻辑是否应该短路,或者您可以在 attribute_CheckedChanged 中取消订阅 all_CheckedChanged 并在最后重新订阅。

    【讨论】:

    • 太棒了,没想到。谢谢,如果没有其他答案,我会尽快接受:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    相关资源
    最近更新 更多