Get the list of Child controls inside a groupbox

I create one method by the ability to find any controls (or T type) and any inherited object from Control (or T type) for you:

public static List<T> GetSubControlsOf<T>(Control parent) where T : Control
{
       var myCtrls = new List<T>();

       foreach (Control ctrl in parent.Controls)
       {
           // if ctrl is type of T
           if (ctrl.GetType() == typeof(T) || 
               ctrl.GetType().IsInstanceOfType(typeof(T)))  
           {
                myCtrls.Add(ctrl as T);
           }
           else if (ctrl.HasChildren)
           {
                var childs = GetSubControlsOf<T>(ctrl);    
                if (childs.Any()) 
                   myCtrls.AddRange(childs);
           }
       }

       return myCtrls;
 }

and use that this form for e.g:

foreach (var textbox in GetSubControlsOf<TextBox>(this))
{
       validData &= !string.IsNullOrWhiteSpace(textbox.Text);
}

A one liner slution,

IEnumerable<TextBox> collection = grpBxTargetSensitivity.Children.OfType<TextBox>(); //assuming you are looking for TextBox

or

You can try following generic method,

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                yield return (T)child;
            }

            foreach (T childOfChild in FindVisualChildren<T>(child))
            {
                yield return childOfChild;
            }
        }
    }
}

then enumerate over the controls as follows,

foreach (TextBox tb in FindVisualChildren<TextBox>(grpBxTargetSensitivity)) //assuming you are looking for TextBox
{
    // do something
}

I don't know that this is any better.. whether it's easier to read is a matter of opinion:

var validData
    = grpBxTargetSensitivity.Controls.OfType<FlowLayoutPanel>()
                            .SelectMany(c => c.Controls.OfType<Panel>())
                            .SelectMany(c => c.Controls.OfType<TextBox>())
                            .All(textbox => !string.IsNullOrWhiteSpace(textbox.Text));

This'll grab all TextBoxes inside of all Panels in all FlowLayoutPanels in your GroupBox, and return true if all of those TextBoxes have a value in them.

Tags:

C#

Linq