17

I have a groupbox in my application which contains child controls.(As seen in the attchached pic). I want to enumerate through all the textboxes for performing some validation using a simple foreach loop.

This document outline would give a fair idea of the housing of the controls

enter image description here

foreach (Control control in grpBxTargetSensitivity.Controls)
            {
                if (control is FlowLayoutPanel && control.HasChildren)
                {
                    foreach (Control ctrl in control.Controls)
                    {
                        if (ctrl is Panel && ctrl.HasChildren)
                        {
                            foreach (Control tbox in ctrl.Controls)
                            {
                                if (tbox is TextBox)
                                {
                                    TextBox textbox = tbox as TextBox;
                                    validData &= !string.IsNullOrWhiteSpace(textbox.Text);
                                }
                            }
                        }
                    }
                }
            }

My question is, Is there a better way (possibly through LINQ) to get all the controls including the textboxes housed inside the panels than the above method.?

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
this-Me
  • 2,139
  • 6
  • 43
  • 70

4 Answers4

20

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.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
  • 1
    Perfect ! Thanks a ton. Is there a way in LINQ I can add a condition in the above query to filter out some textboxes ? – this-Me May 18 '15 at 05:03
5

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
}
Abhishek
  • 6,912
  • 14
  • 59
  • 85
4

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);
}
Behzad
  • 3,502
  • 4
  • 36
  • 63
2

I found following links on StackOverflow itself:

How to get ALL child controls of a Windows Forms form of a specific type (Button/Textbox)?

Loop through all the user controls on a page

Give them try. Should work in your case.

Community
  • 1
  • 1
Priyank Sheth
  • 2,352
  • 19
  • 32