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

Rya*_*hel 13 c# controls winforms

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

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

按钮之所以重要,是因为我不能使用禁用窗口或其他东西的方法,因为一个控件仍然需要可用.

pin*_*x33 27

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

 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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • @ Hi-Angel:递归调用是必要的,因为Winforms中的父/子关系是递归的.在许多形式中,只有一个级别的后代,因此不需要递归,但是一个好的,通用的解决方案需要在所有情况下都能工作,而不仅仅是你测试的那个. (4认同)

col*_*oxp 13

基于@ 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
                {
                }
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

private void Form1_Load(object sender, EventArgs e) 
{
        this.Enable(false);
        Button1.Enable(true);
}
Run Code Online (Sandbox Code Playgroud)

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


Neo*_*isk 9

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

如果您真的想保留当前的设计,可以将ControlCollection树线性化为Control数组以避免递归,然后执行以下操作:

Array.ForEach(Me.Controls.GetAllControlsOfType(Of Control), Sub(x As Control) x.Enabled = False)
yourButton.Enabled = True
Run Code Online (Sandbox Code Playgroud)