Share via


Get an array of all TextBox controls in a form

Question

Wednesday, August 24, 2011 6:01 AM

Is there a way to get an array of all controls in a form by type or by a partial string match of the control name?

All of my TextBoxes are named TextBox.Name = <name>_Text<appendage>. What I want to do is something like:

Control [] allTextBoxControls = this.Controls.Find("_Text", true), however, this doesn't work because the string needs to be an exact match of a control name.

Is there another way (like building an array or collection by control type)?

 

Thanks  :)

All replies (12)

Wednesday, August 24, 2011 6:35 AM ✅Answered | 1 vote

Best way would by to write your own method to find the controls:

public void FindControls(Control owner, List<Control> list, string name) {
    foreach (Control c in owner.Controls) {
        if (c.Name.Contains(name)) {
            list.Add(c);
        }
        if (c.HasChildren) FindControls(c, list, name);
    }
}

//Call it like this:
List<Controls> clist = new List<Controls>();
FindControls(this, clist, "_Text");

This Method iterates through all controls and subcontrols and add it to the list


Wednesday, August 24, 2011 6:39 AM ✅Answered | 1 vote

Or if you still want to search based on "_Text", just change the code as below,

List<TextBox> allTextBoxControls = new List<TextBox>(); //This List contains all TextBoxes
public void GetAllTextBoxes(Control.ControlCollection controls)
{
  foreach (Control ctl in controls)
  {
    GetAllTextBoxes(ctl.Controls);
    if (ctl.Text.Contains("_Text"))
    {
      allTextBoxControls.Add(ctl as TextBox);
    }
  }
}

 

Please mark this post as answer if it solved your problem. Happy Programming!


Wednesday, August 24, 2011 7:19 AM ✅Answered | 1 vote

Hi

Yes, this function does not goes through deep. What i would suggest is 

having a Extension method like 

 

 public static class ControlExtension
  {
    public static IList<T> FindControlByName<T>(this Control control, string name) where T : Control
    {
      List<T> controlsFound = new List<T>();

      controlsFound.AddRange(control.Controls.OfType<T>().Where(t => t.Name.Contains(name)));
      foreach (Control c in control.Controls)
      {
        controlsFound.AddRange(FindControlByName<T>(c, name));
      }
      return controlsFound;
    }
  }

And use in Form like 

 var controlsFound = this.FindControlByName<TextBox>("partialname");

 

If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".


Wednesday, August 24, 2011 6:38 AM | 1 vote

If you want to get all textBoxes why do you want to search by it's name? You can do it as,

List<TextBox> allTextBoxControls = new List<TextBox>(); //This List stores all textBoxes

public void GetAllTextBoxes(Control.ControlCollection controls)
{
  foreach (Control ctl in controls)
  {
    GetAllTextBoxes(ctl.Controls);
    if (ctl is TextBox)
    {
      allTextBoxControls.Add(ctl as TextBox);
    }
  }
}

Hope this helps. 

Please mark this post as answer if it solved your problem. Happy Programming!


Wednesday, August 24, 2011 6:40 AM | 1 vote

Hi 

Check wwith this

var textControls = this.Controls.OfType<TextBox>().Where(t => t.Name.Contains("partialName"))

If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".


Wednesday, August 24, 2011 6:46 AM

Hi Kris444,

does this call also find controls in Panels and TabSheets or only controls in the this.Controls collection.


Wednesday, August 24, 2011 6:54 AM

Hi Kris444,

does this call also find controls in Panels and TabSheets or only controls in the this.Controls collection.

Try my code. It does.Please mark this post as answer if it solved your problem. Happy Programming!


Wednesday, August 24, 2011 8:15 AM | 1 vote

You don't really need to store an array of all the controls if you are just iterating through them.

I suggest the following:

Firstly, define this useful extension method that recursively returns all the controls:

public static class ControlExt
{
  public static IEnumerable<Control> AllControls(this Control parent)
  {
    if (parent == null)
    {
      throw new ArgumentNullException("parent");
    }

    foreach (Control control in parent.Controls)
    {
      foreach (Control child in AllControls(control))
      {
        yield return child;
      }

      yield return control;
    }
  }

Then you can use the normal Linq "OfType()" extension to filter the list with whatever type you desire, for example (for TextBox):

foreach (var control in parentControl.AllControls().OfType<TextBox>())
{
  // Do something with 'control'.
}

Wednesday, August 24, 2011 9:02 AM

Hi Kris444,

does this call also find controls in Panels and TabSheets or only controls in the this.Controls collection.

Try my code. It does. Please mark this post as answer if it solved your problem. Happy Programming!

Really, I see in your code only the controls in the control collection of the form, not the control collections which are in panels, splitters, groupboxes etc.

It is possible to do this with recursive coding, 

Success
Cor


Wednesday, August 24, 2011 9:32 AM | 1 vote

One more version (that will be all now :) ):

With a Generic help:

  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
      
      //you wanna get all the buttons here:
      List<Button> listOfButtons = new List<Button>();
      foreach (var button in this.GetControls<Button>())
      {
        listOfButtons.Add(button);
      }
    }
  }

  static class ExtensionMethods
  {
    public static IEnumerable<T> GetControls<T>(this Control root) where T : Control
    {
      foreach (Control control in root.Controls)
      {
        T test = control as T;
        if (test != null) yield return test;
        foreach (T subcontrol in GetControls<T>(control))
          yield return subcontrol;
      }
    }
  }

 

Mitja


Wednesday, August 24, 2011 5:05 PM

Thanks to all of you  :)

 

Adavesh, your code worked great for my purposes with the exception that I use if (ctl.Name.Contains("_Text")) instead of if (ctl.Text.Contains("_Text")).

I do need to search through TabPages and TableLayPanels, this routine works great.

There are a few TextBoxes where I did not put "_Text_ in TextBox.Name. I handle the data from those differently, that's why I needed to distinguish between all TextBoxes and those with _Text in the name.

 

You guys are awesome  !!


Wednesday, August 24, 2011 5:34 PM

So, can you mark the post as answered?Please mark this post as answer if it solved your problem. Happy Programming!