除了按钮之外,如何禁用表单上的所有控件?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了除了按钮之外,如何禁用表单上的所有控件?相关的知识,希望对你有一定的参考价值。

我的表单有数百个控件:菜单,面板,分割器,标签,文本框,您可以命名。

除了单个按钮之外,有没有办法禁用每个控件?

按钮重要的原因是因为我无法使用禁用窗口或其他东西的方法,因为一个控件仍然需要可用。

答案

您可以执行递归调用以禁用所涉及的所有控件。然后,您必须启用您的按钮和任何父容器。

 private void Form1_Load(object sender, EventArgs e) {
        DisableControls(this);
        EnableControls(Button1);
    }

    private void DisableControls(Control con) {
        foreach (Control c in con.Controls) {
            DisableControls(c);
        }
        con.Enabled = false;
    }

    private void EnableControls(Control con) {
        if (con != null) {
            con.Enabled = true;
            EnableControls(con.Parent);
        }
    }
另一答案

基于@ pinkfloydx33的答案以及我对它进行的编辑,我创建了一个扩展方法,使其更加简单,只需创建一个像这样的public static class

public static class GuiExtensionMethods
{
        public static void Enable(this Control con, bool enable)
        {
            if (con != null)
            {
                foreach (Control c in con.Controls)
                {
                    c.Enable(enable);
                }

                try
                {
                    con.Invoke((MethodInvoker)(() => con.Enabled = enable));
                }
                catch
                {
                }
            }
        }
}

现在,启用或禁用控件,表单,菜单,子控件等。只需:

this.Enable(true); //Will enable all the controls and sub controls for this form
this.Enable(false);//Will disable all the controls and sub controls for this form

Button1.Enable(true); //Will enable only the Button1

所以,我会做什么,类似于@ pinkfloydx33的回答:

private void Form1_Load(object sender, EventArgs e) 
{
        this.Enable(false);
        Button1.Enable(true);
}

我喜欢Extension方法,因为它们是静态的,你可以在任何地方使用它而无需创建实例(手动),至少对我来说它更清晰。

另一答案

为了更好,更优雅的解决方案,这很容易维护 - 您可能需要重新考虑您的设计,例如将您的按钮放在其他控件旁边。然后假设其他控件在面板或组框中,只需执行Panel.Enabled = False

如果您真的想保留当前的设计,可以使用Linearise ControlCollection tree into array of Control来避免递归,然后执行以下操作:

Array.ForEach(Me.Controls.GetAllControlsOfType(Of Control), Sub(x As Control) x.Enabled = False)
yourButton.Enabled = True
另一答案

当你有许多面板或tableLayoutPanels嵌套时,情况变得棘手。尝试禁用面板中禁用父面板然后启用子控件的所有控件根本不启用控件,因为父节点(或父节点的父节点)未启用。为了保持启用所需的子控件,我将表单布局视为树,表单本身作为根,任何容器或面板作为分支和子控件(按钮,文本框,标签等)作为叶节点。因此,主要目标是禁用与所需控件相同级别的所有节点,将控制树一直爬到表单级别,建立启用控件的路径,以便子级可以工作:

public static void DeshabilitarControles(Control control)
{
    if (control.Parent != null)
    {
        Control padre = control.Parent;
        DeshabilitarControles(control, padre);
    }
}

private static void DeshabilitarControles(Control control, Control padre)
{
    foreach (Control c in padre.Controls)
    {
        c.Enabled = c == control;
    }
    if (padre.Parent != null)
    {
        control = control.Parent;
        padre = padre.Parent;
        DeshabilitarControles(control, padre);
    }
}

public static void HabilitarControles(Control control)
{
    if (control != null)
    {
        control.Enabled = true;
        foreach (Control c in control.Controls)
        {
            HabilitarControles(c);
        }
    }
}

以上是关于除了按钮之外,如何禁用表单上的所有控件?的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF 窗口中禁用除一个子控件之外的所有子控件

禁用控件后在 Access VBA 中显示禁用的控件

根据文本控件值标记和启用/禁用连续表单上的按钮

使用 javascript 禁用 asp.net 单选按钮

按钮控件需要一些时间才能在对话框中禁用

无法在加载时禁用ms-access userform的所有字段