Although
this was originally part of my recent Generics presentation, I have received several
requests to publish it separately.
The
reason that I created this originally was that I found myself often-times wanting
a strongly-typed list of all the checkboxes / buttons / etc in my code-behind/beside
pages. There is the Page.FindControl(string
id), but that only allows you to get a control by id and it returns a Control. I
wanted something more specific, yet generic enough to use as a Utility. This
was screaming for Generic Methods, so below is what I came up with.
I
use this constantly and hope that someone else gets some mileage out of it. If
you have improvements, please post them. For
example usage, download the full Generics presentation.
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace r2musings.Web.UI.WebControls
{
public static class Utility
{
#region FindControlsByType
/// <summary>
/// Returns
a generic list of controls of a provided type starting at a
/// a
provided base control (works recursively)
/// Example
Usage:
/// List<Button> buttonList
= Utility.FindControlsByType<Button>(testPanel);
/// This
would return a list of all Buttons contained anywhere within testPanel
/// </summary>
/// <typeparam
name="T">Type of control</typeparam>
/// <param
name="parentControl">Base control to start search</param>
/// <returns></returns>
public static List<T>
FindControlsByType<T>(Control parentControl) where T:
System.Web.UI.Control
{
//
new up our return list
List<T>
returnList = new List<T>();
//
loop through all controls and call internal recursion to
// add
all controls of type T to the returnList
foreach (Control childControl in parentControl.Controls)
{
InternalFindControlsByType<T>(childControl,
returnList);
}
//
return our List<T>
return returnList;
}
#endregion
#region Recursion
Method
/// <summary>
/// Should
NOT call this method directly
/// This
is for the internal recursion of FindControlsByType()
/// </summary>
/// <typeparam
name="T">Type of control</typeparam>
/// <param
name="parentControl">Base control to start search</param>
/// <param
name="returnList">List to add Controls</param>
private static void InternalFindControlsByType<T>(Control parentControl, List<T>
returnList) where T: System.Web.UI.Control
{
if (returnList
== null)
throw new ArgumentNullException("Null
List passed to InternalFindControlsByType");
if (parentControl is T)
{
returnList.Add((T)
parentControl);
}
foreach (Control childControl in parentControl.Controls)
{
//
call this method recursively to get all child controls
InternalFindControlsByType(childControl,
returnList);
}
}
#endregion
}
}