Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make all Controls on a Form read-only at once

Does anyone have a piece of code to make all Controls (or even all TextBoxes) in a Form which is read-only at once without having to set every Control to read-only individually?

like image 313
Nick LaMarca Avatar asked Sep 01 '10 13:09

Nick LaMarca


4 Answers

Write an extension method which gathers controls and child controls of specified type:

public static IEnumerable<T> GetChildControls<T>(this Control control) where T : Control
{
    var children = control.Controls.OfType<T>();
    return children.SelectMany(c => GetChildControls<T>(c)).Concat(children);
}

Gather TextBoxes on the form (use TextBoxBase to affect RichTextBox, etc - @Timwi's solution):

IEnumerable<TextBoxBase> textBoxes = this.GetChildControls<TextBoxBase>();

Iterate thru collection and set read-only:

private void AreTextBoxesReadOnly(IEnumerable<TextBoxBase> textBoxes, bool value)
{
    foreach (TextBoxBase tb in textBoxes) tb.ReadOnly = value;
}

If want - use caching - @igor's solution

like image 153
abatishchev Avatar answered Nov 20 '22 22:11

abatishchev


In Form:

if (_cached == null)
{
    _cached = new List<TextBox>();

    foreach(var control in Controls)
    {
        TextBox textEdit = control as TextBox;
        if (textEdit != null)
        {
            textEdit.ReadOnly = false;
            _cached.Add(textEdit);
        }
    }
} 
else
{
    foreach(var control in _cached)
    {            
        control .ReadOnly = false;
    }
}

Add recursion also (Controls can be placed into other controls (panels)).

like image 38
garik Avatar answered Nov 20 '22 22:11

garik


You should be able to write yourself a utility function to do this. You can iterate over the form’s controls and then each control’s child controls recursively. For example:

public static void SetEnableOnAllControls(Control parentControl, bool enable)
{
    parentControl.Enabled = enable;
    foreach (Control control in parentControl.Controls)
        SetEnableOnAllControls(control, enable);
}

[...]

// inside your form:
SetEnableOnAllControls(this, false);

This doesn’t take care of ToolStrips, which aren’t controls. You could write a separate, similar method for those.

Notice that the above disables the form itself too. If you don’t want that, try this:

public static void SetEnableOnAllChildControls(Control parentControl, bool enable)
{
    foreach (Control control in parentControl.Controls)
    {
        control.Enabled = enable;
        SetEnableOnAllChildControls(control, enable);
    }
}

If you really meant the ReadOnly property, which is only relevant for TextBoxes, try this:

public static void SetReadOnlyOnAllControls(Control parentControl, bool readOnly)
{
    if (parentControl is TextBoxBase)
        ((TextBoxBase) parentControl).ReadOnly = readOnly;
    foreach (Control control in parentControl.Controls)
        SetReadOnlyOnAllControls(control, readOnly);
}
like image 4
Timwi Avatar answered Nov 20 '22 21:11

Timwi


I would use reflection to check to see if the generic Control object has an Enabled property.

private static void DisableControl(Control control)
{
    PropertyInfo enProp = control.GetType().GetProperty("Enabled");
    if (enProp != null)
    {
        enProp.SetValue(control, false, null);
    }

    foreach (Control ctrl in control.Controls)
    {
        DisableControl(ctrl);
    }
}
like image 3
CodeWizard Avatar answered Nov 20 '22 20:11

CodeWizard