Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable all controls on the form except for a button?

My form has hundreds of controls: menus, panels, splitters, labels, text boxes, you name it.

Is there a way to disable every control except for a single button?

The reason why the button is significant is because I can't use a method that disables the window or something because one control still needs to be usable.

like image 278
Ryan Peschel Avatar asked Nov 19 '12 00:11

Ryan Peschel


3 Answers

You can do a recursive call to disable all of the controls involved. Then you have to enable your button and any parent containers.

 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);
        }
    }
like image 123
pinkfloydx33 Avatar answered Nov 10 '22 06:11

pinkfloydx33


Based on @pinkfloydx33's answer and the edit I made on it, I created an extension method that makes it even easier, just create a public static class like this:

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

Now, to enable or disable a control, form, menus, subcontrols, etc. Just do:

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

So, what I would do, similar as @pinkfloydx33's answer:

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

I like Extension methods because they are static and you can use it everywhere without creating instances (manually), and it's much clearer at least for me.

like image 14
coloboxp Avatar answered Nov 10 '22 05:11

coloboxp


For a better, more elegant solution, which would be easy to maintain - you probably need to reconsider your design, such as put your button aside from other controls. Then assuming other controls are in a panel or a groupbox, just do Panel.Enabled = False.

If you really want to keep your current design, you can Linearise ControlCollection tree into array of Control to avoid recursion and then do the following:

Array.ForEach(Me.Controls.GetAllControlsOfType(Of Control), Sub(x As Control) x.Enabled = False)
yourButton.Enabled = True
like image 9
Neolisk Avatar answered Nov 10 '22 05:11

Neolisk