Loop through all controls of a Form, even those in GroupBoxes

后端 未结 9 1120
囚心锁ツ
囚心锁ツ 2020-11-29 05:17

I\'d like to add an event to all TextBoxes on my Form:

foreach (Control C in this.Controls)
{
    if (C.GetType() == typeof(System.Windows.Forms         


        
相关标签:
9条回答
  • 2020-11-29 05:54

    I know that this is an older topic, but would say the code snippet from http://backstreet.ch/coding/code-snippets/mit-c-rekursiv-durch-form-controls-loopen/ is a clever solution for this problem.

    It uses an extension method for ControlCollection.

    public static void ApplyToAll<T>(this Control.ControlCollection controlCollection, string tagFilter, Action action)
    {
        foreach (Control control in controlCollection)
        {
            if (!string.IsNullOrEmpty(tagFilter))
            {
                if (control.Tag == null)
                {
                    control.Tag = "";
                }
    
                if (!string.IsNullOrEmpty(tagFilter) && control.Tag.ToString() == tagFilter && control is T)
                {
                    action(control);
                }
            }
            else
            {
                if (control is T)
                {
                    action(control);
                }
            }
    
            if (control.Controls != null && control.Controls.Count > 0)
            {
                ApplyToAll(control.Controls, tagFilter, action);
            }
        }
    }
    

    Now, to assign an event to all the TextBox controls you can write a statement like (where 'this' is the form):

    this.Controls.ApplyToAll<TextBox>("", control =>
    {
        control.TextChanged += SomeEvent
    });
    

    Optionally you can filter the controls by their tags.

    0 讨论(0)
  • 2020-11-29 06:08

    Updated answer:

    I needed to disable all the controls in a form, including groupboxes. This code worked:

        private void AlterControlsEnable(bool ControlEnabled)
        {
            foreach (Control i in Controls)
                i.Enabled = ControlEnabled;
        }
    
    0 讨论(0)
  • 2020-11-29 06:11

    The Controls collection of Forms and container controls contains only the immediate children. In order to get all the controls, you need to traverse the controls tree and to apply this operation recursively

    private void AddTextChangedHandler(Control parent)
    {
        foreach (Control c in parent.Controls)
        {
            if (c.GetType() == typeof(TextBox)) {
                c.TextChanged += new EventHandler(C_TextChanged);
            } else {
                AddTextChangedHandler(c);
            }
        }
    }
    

    Note: The form derives (indirectly) from Control as well and all controls have a Controls collection. So you can call the method like this in your form:

    AddTextChangedHandler(this);
    

    A more general solution would be to create an extension method that applies an action recursively to all controls. In a static class (e.g. WinFormsExtensions) add this method:

    public static void ForAllControls(this Control parent, Action<Control> action)
    {
        foreach (Control c in parent.Controls) {
            action(c);
            ForAllControls(c, action);
        }
    }
    

    The static classes namespace must be "visible", i.e., add an appropriate using declaration if it is in another namespace.

    Then you can call it like this, where this is the form; you can also replace this by a form or control variable whose nested controls have to be affected:

    this.ForAllControls(c =>
    {
        if (c.GetType() == typeof(TextBox)) {
            c.TextChanged += C_TextChanged;
        }
    });
    
    0 讨论(0)
提交回复
热议问题