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.
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);
}
}
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With