There are times in any semi-advanced ASP.NET developer's life when they’re working with databound templated controls (such as the Repeater) and they need to find a control without knowing where it is, or even if it's there.
Normally, you’re reduced to using the standard FindControl
method available on any control. But this only finds controls with a given id within the same NamingContainer
.
I’ve written some extension methods to try and get around the (many) issues that I’ve had with FindControl
and hopefully people will find them useful.
Get All Child Controls of a Given Type
public static IEnumerable<T> GetAllChildControlsOfType<T>
(this Control parent) where T : Control
{
if (parent == null) throw new ArgumentNullException("parent");
foreach (Control c in parent.Controls)
{
if (typeof(T).IsInstanceOfType(c)) yield return (T)c;
foreach (T tc in c.GetAllChildControlsOfType<T>())
yield return tc;
}
yield break;
}
Get All Child Controls that Implement a Given Interface
For when you don’t care what the control is, as long as it can do a particular thing….try it with IButtonControl
.
public static IEnumerable<T> GetAllChildControlsWithInterface<T>(this Control parent)
{
if (!typeof(T).IsInterface) throw new NotSupportedException
(string.Format(CultureInfo.InvariantCulture,"Type '{0}'
is not an interface".ToFormattedString(typeof(T).ToString()));
if (parent == null) throw new ArgumentNullException("parent");
foreach (object c in parent.Controls)
{
if (typeof(T).IsInstanceOfType(c))
yield return (T)c;
Control ctrl = c as Control;
if (ctrl != null)
foreach (T tc in ctrl.GetAllChildControlsWithInterface<T>())
yield return tc;
}
yield break;
}
Find All Controls With a Given ID
Find every Textbox
with an Id of ‘FirstName
’ within a repeater….
public static IEnumerable<T> FindAllControl<T>
(this Control parent, string id) where T : Control
{
if (string.IsNullOrEmpty(id)) throw new ArgumentNullException("id");
return parent.GetAllChildControlsOfType<T>()
.Where(c => string.Equals(c.ID, id, StringComparison.OrdinalIgnoreCase));
}
Find The First Control with an ID
public static T FindControl<T>(this Control parent, string id) where T : Control
{
return parent.FindAllControl<T>(id).FirstOrDefault();
}