Get all components in all open forms

Peter Volz 1,155 Reputation points
2023-07-27T13:53:30.12+00:00

Hello,

As title says:

For Each MyForm As Form In Application.OpenForms
   For Each MyComponent As Object In MyForm.components.Components
   'components' is not a member of 'System.Windows.Forms.Form'

No idea how to loop through all components in all open forms :(

Please help

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
9,989 questions
VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,510 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Karen Payne MVP 35,021 Reputation points
    2023-07-27T17:33:30.6866667+00:00

    Try this

    public IEnumerable<Component> GetComponents(Control c)
    {
        FieldInfo fi = c.GetType().GetField("components", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)!;
        if (fi?.GetValue(c) is IContainer container)
        {
            return container.Components.OfType<Component>();
        }
        else
        {
            return Enumerable.Empty<Component>();
        }
    }
    

    Usage

    foreach (Form form in Application.OpenForms)
    {
        var componentList = GetComponents(form).ToList();
    }
    

    And for constrols where Decendant gets all controls on a form. Note the wrapper for getting all TextBoxes which can be done for other controls also.

    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WindowsFormsLibrary.LanguageExtensions
    {
        public static class FormExtensions
        {
            public static IEnumerable<T> Descendant<T>(this Control control) where T : class
            {
                foreach (Control child in control.Controls)
                {
                    if (child is T thisControl)
                    {
                        yield return (T)thisControl;
                    }
    
                    if (child.HasChildren)
                    {
                        foreach (T descendant in Descendant<T>(child))
                        {
                            yield return descendant;
                        }
                    }
                }
            }
            public static List<TextBox> TextBoxList(this Control control)
                => control.Descendants<TextBox>().ToList();
        }
    }
    
    
    1 person found this answer helpful.