c# - Iterating through form's text boxes

Saga 431 Reputation points
2023-12-06T18:32:16.6+00:00

Hi all, I am using VS 2019, c#, Windows 10 Pro.

I need to validate the Text in the form's textboxes. I could do something like

ValidateText(TextBox1);

ValidateText(TextBox2);

ValidateText(TextBox3);

and so forth, but thought that iterating through the form's text boxes was a better solution. I tried the following:

foreach (Control ctrl in this.Controls)

{

if (ctrl.GetType().Equals(typeof(TextBox)))

{

//You can cast ctrl to TextBox and then extract the data that you need from it

}

}

This works fine for cases when the text boxes are directly on the form, but not so good when they are inside a container.

After some more searching I found the following on StackOverflow:

https://stackoverflow.com/questions/4863051/loop-through-textboxes

I implemented the checked solution of using an extension method. The result:

The static class:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace CustomExtensions

{

public static class clsCustomExtensions

{

public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control

{

var children = (control.Controls != null) ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();

return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);

}

}

}

Usage:

using CustomExtensions;

var allTextBoxes = this.GetChildControls<TextBox>();

foreach (TextBox tb in allTextBoxes)

{

bDataOK = bDataOK || sysValidateVendorFields(tb);

}

The allTextBoxes variable is coming back empty. As additional information, I have the textboxes inside a GroupBox. Any suggestions how I can diagnose this? Thank you!

Developer technologies | C#
0 comments No comments
{count} votes

Accepted answer
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-12-06T19:15:22.2933333+00:00

    Add the following class to your project.

    public static class ControlExtensions
    {
    
        public static IEnumerable<T> Descendants<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 Descendants<T>(child))
                    {
                        yield return descendant;
                    }
                }
            }
        }
        
        public static List<TextBox> TextBoxList(this Control control)
            => control.Descendants<TextBox>().ToList();
    
    }
    

    Usage in a form.

    Example 1:

    Are there any empty TextBox controls on the form or in say a panel or group box?

    string[] textBoxes = this.TextBoxList()
        .Where(tb => string.IsNullOrWhiteSpace(tb.Text))
        .Select(tb => tb.Name)
        .ToArray();
    

    Example 2:

    Get all TextBoxes and iterate

    TextBox[] textBoxes = this.TextBoxList().ToArray();
    foreach (var textBox in textBoxes)
    {
       // do validation
    }
    

    A better idea

    Is to use Data Annotations but not getting into that here as it requires more of an effort and experience with C#.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,926 Reputation points Volunteer Moderator
    2023-12-06T19:03:51.46+00:00

    you code only recurses on controls of that match the type.

    try:

    public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
    {
       if (control.Controls == null)
           return Enumerable.Empty<TControl>();
    
       return control.Controls.OfType<TControl>()
            .Concat(control.Controls.SelectMany(c => GetChildControls<TControl>(c));
    }
    
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.