【问题标题】:Check if all checkboxes of form are checked检查表单的所有复选框是否都被选中
【发布时间】:2019-01-04 06:59:41
【问题描述】:

我有多个从代码中动态创建的复选框,所以我知道我可以使用以下方法获取复选框:

foreach (var checkBox in this.Controls.OfType<CheckBox>())
            {

            }

但是我想知道或者我想要的结果是知道我的表单的所有复选框是否都被选中,如果所有复选框都被选中,则返回 true,如果缺少一个,则返回 false……我怎样才能做到这一点?问候

bool allChecked = ... 

【问题讨论】:

  • 你不能通过反转 where 子句的逻辑并检查计数是否等于 0 来获得所有未检查的控件吗?
  • 面板或其他容器中是否有任何复选框?
  • 使用上面的代码,您可以从bool allChecked = true; 开始,在foreach 中添加以下行:if (!checkbox.Checked) { allChecked = false; break; }

标签: c# winforms


【解决方案1】:

简单来说

bool allChecked = this.Controls.OfType<CheckBox>().All(c => c.Checked);

我不确定AllControls(在未经编辑的原始帖子中)是什么。因为这个属性似乎不是一个标准的。此示例使用任何控件容器(如顶级表单)中存在的标准控件集合

如果您将 CheckBox 分布在不同的控件容器中,则问题会更加复杂。在这种情况下,您可以使用递归函数迭代地探索您的控件并计算其中有多少被检查

int result = RecursiveCheck(f.Controls);
if(result > 0)
    Console.WriteLine("Something is not checked");

int RecursiveCheck(Control.ControlCollection col)
{
    int count = 0;
    foreach(Control c in col)
    {
        if (c.Controls.Count > 0)
        {
            count += c.Controls.OfType<CheckBox>().Count(x => !x.Checked);
            count += RecursiveCheck(c.Controls);
        }   
    }
    return count;
}

【讨论】:

  • 我试了一下,总是返回真值
  • 您的复选框是否位于某种容器中? (面板或组框)这种情况下需要使用容器的控件集合
  • 是的,它们在 FlowLayoutPanel 中
  • 然后将 this 更改为您的 FlowLayoutPanel 的名称
  • 问题是它们在 FlowLayoutPanel 内,但在里面我有 GroupBoxes,所以每个 GroupBox 都有不同的复选框,我有 groupBox 列表,所以我迭代为:foreach (var g in groupBoxes) { },但是现在,我怎么知道如果所有复选框都在不同的 Groupboxes 中,是否都被选中?
【解决方案2】:

如果您想验证表单上的所有复选框是否都被选中,即使是那些属于其他容器控件的复选框,您必须遍历每个控件的 Controls 集合(不仅仅是属于 Form 的那些)。

执行此操作的一种方法是编写一个递归方法,该方法接收容器控件(如Form)并检查其集合中的所有控件。如果任何包含的控件是 Checkbox 并且未选中,则返回 false。否则,对该控件的Controls 集合执行递归检查。如果这些检查都不为假,则返回真。

例如:

private static bool ContainedCheckboxesAreChecked(Control containerControl)
{        
    // For each control in the container
    foreach (Control control in containerControl.Controls)
    {
        // Return false if the control is a checkbox and it's not checked
        if (!(control as CheckBox)?.Checked ?? false) return false;

        // Do a recursive check on this control's Controls collection
        if (!ContainedCheckboxesAreChecked(control)) return false;
    }

    // If we got this far, return true
    return true;
}

现在,如果您调用它并将主窗体作为容器控件传入,您将检查窗体上的所有控件,包括所有容器(甚至是嵌套容器)中的控件:

bool allCheckBoxesAreChecked = ContainedCheckboxesAreChecked(this);

【讨论】:

    【解决方案3】:

    如果您确定复选框可用,则可以使用

     var allChecked = this.Controls.OfType<CheckBox>().All(x => x.Checked);
    

    但是如果Enumerable 有可能没有结果,那么您需要使用下面的代码。因为 All 运算符返回 true 为空的 Enumerable

        bool allChecked = false;
        var checkBoxes = this.Controls.OfType<CheckBox>();
        if (checkBoxes.Any())
            allChecked = checkboxes.All(x => x.Checked);
    

    【讨论】:

    • 我尝试过,但它总是返回 True 值
    • 它返回 true 但这可能是不可取的,因为在您的 this.Controls 中找不到复选框
    猜你喜欢
    • 1970-01-01
    • 2021-08-19
    • 2012-12-08
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 2021-07-16
    相关资源
    最近更新 更多