Find Controls in Controls recursively using Generics

Posted on March 24, 2007. Filed under: controls |

The two methods below recursively search for a control within a control. The first searches for a Textbox and the second searches for a DropDownList. The methods also accept the position of the control, e.g. 0 for the first TextBox, 1 for the second Textbox. I was using these methods to find controls within a WizardStep before I discovered generics (see below for better, more generic solution).

private TextBox FindTextBox(Control c, int positionOfControl)
{
   _positionOfControl = positionOfControl;
   if (c == null) return null;
   if (typeof(TextBox) == c.GetType())
   {
      if (_positionOfControl == 0)
      {
         return c as TextBox;
      }
      else
      {
         _positionOfControl--;
      }
   }

   Control results;
   foreach (Control child in c.Controls)
   {
      results = FindTextBox(child, _positionOfControl);
      if (results != null && typeof(TextBox) == results.GetType())
      {
         return results as TextBox;
      }
   }
   return null;}

and

private DropDownList FindDropDownList(Control c, int positionOfControl)
{
   _positionOfControl = positionOfControl;
   if (c == null) return null;
   if (typeof(DropDownList) == c.GetType())
   {
      if (_positionOfControl == 0)
      {
         return c as DropDownList;
      }
      else
      {
         _positionOfControl--;
      }
   }

   Control results;
   foreach (Control child in c.Controls)
   {
      results = FindDropDownList(child, _positionOfControl);
      if (results != null && typeof(DropDownList) == results.GetType())
      {
         return results as DropDownList;
      }
   }

   return null;}

To find the first TextBox in a WizardStep I’d write the following code:

TextBox textbox = FindTextBox(Wizard1.WizardStep[1], 0);

This works fine but leads to code bloat if you need to search for different type of controls. Enter Generics.

Generics Solution

It’s all in the name and the code below demonstrates a perfect use for generics. The code is verbose enough to not require explaination.

private T FindControl<Control>(Control c, int positionOfControl) Where T:Control
{
   _positionOfControl = positionOfControl;
   if (c == null) return null;
   if (typeof(T) == c.GetType())
   {
      if (_positionOfControl == 0)
      {
         return c as T;
      }
      else
      {
         _positionOfControl--;
      }
   }
   
   Control results;
   foreach (Control child in c.Controls)
   {
      results = FindControl(child, _positionOfControl);
      if (results != null && typeof(T) == results.GetType())
      {
         return results as T;
      }
   }

   return null;}

To use this method just code:

Textbox textBox = FindControl<TextBox>(Wizard1.WizardStep[1],0)

or

DropDownList dropDownList = FindControl<DropDownList>(Wizard1.WizardStep[1], 0)

Tags: , ,

Make a Comment

Make a Comment: ( 2 so far )

blockquote and a tags work here.

2 Responses to “Find Controls in Controls recursively using Generics”

RSS Feed for dotnetting Comments RSS Feed

I never see this! Really helpful.

public static Control FindControlRecursive (ref Control root, ref string id )
{
if (root.ID == id)
{
return root;
}

foreach (Control c in root.Controls)
{
Control a = c;
Control t = FindControlRecursive ( ref a, ref id );
if (t != null)
{
return t;
}
}

return null;
} //eof FindControlRecursive


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...