Make all Controls on a Form read-only at once

前端 未结 7 488
故里飘歌
故里飘歌 2021-01-12 07:40

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 individua

相关标签:
7条回答
  • 2021-01-12 07:52
    this.Enabled = false;
    

    Depends on what you doing really, you might want to consider putting the control within a panel and disabling that.

    0 讨论(0)
  • 2021-01-12 08:05

    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

    0 讨论(0)
  • 2021-01-12 08:07

    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);
        }
    }
    
    0 讨论(0)
  • 2021-01-12 08:09

    I just developed a recursive solution that handles any kind of Web Control, using a simple static method and ASP.NET polymorphysm.

    /// <summary>
    /// Handle "Enabled" property of a set of Controls (and all of the included child controls through recursivity)
    /// By default it disable all, making all read-only, but it can also be uset to re-enable everything, using the "enable" parameter 
    /// </summary>
    /// <param name="controls">Set of controls to be handled. It could be the entire Page.Controls set or all of the childs of a given control (property "Controls" of any Control-derived class)</param>
    /// <param name="enable">Desired value of the property "enable" of each control. </param>
    public static void DisableControls(ControlCollection controls, bool enable = false)
    {
        foreach (Control control in controls)
        {
            var wCtrl = control as WebControl;
            if (wCtrl != null)
            {
                wCtrl.Enabled = enable;
            }
    
            if (control.Controls.Count > 0)
                DisableControls(control.Controls, enable);
        }
    }
    
    /// <summary>
    /// Enable a set of Controls (and all of the included child controls through recursivity).
    /// Friendly name for DisableControls(controls, true), that achieve the same result.
    /// </summary>
    /// <param name="Controls">Set of controls to be handled. It could be the entire Page.Controls set or all of the childs of a given control (property "Controls" of any Control-derived class)</param>
    public static void EnableControls(ControlCollection controls)
    {
        DisableControls(controls, true);
    }
    

    This is tested and looks fairly fast (less than a millisecond in a web form with 25+ controls to be disabled).

    If you prefer an extension method, i think it should be enough to change the solution as follows:

    public static void DisableControls(this Control control, bool enable = false)
    {
        foreach (Control ctrl in control.Controls)
        {
            var wCtrl = ctrl as WebControl;
            if (wCtrl != null)
            {
                wCtrl.Enabled = enable;
            }
    
            if (ctrl.Controls.Count > 0)
                ctrl.DisableControls(enable);
        }
    }
    
    public static void EnableControls(this Control control)
    {
        control.DisableControls(true);
    }
    
    0 讨论(0)
  • 2021-01-12 08:10

    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)).

    0 讨论(0)
  • 2021-01-12 08:14

    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);
    }
    
    0 讨论(0)
提交回复
热议问题