Master of all I can see. At least on this page

Have you ever needed to get access to every control in a page hierarchy when using ASP.NET. I have. In fact, I need to do this a lot. I got a little sick of rewriting the same bit of code over and over and so I ended up with the following helper method:

public static IEnumerable<Control> GetAll(this Control root)
yield return root;
if (root.Controls != null)
foreach (Control child in root.Controls)
foreach (var foundItem in child.GetAll())
yield return foundItem;

Iterators + Recursion is fun. What does this do? The first line returns the current element itself. Then, if the current element has children then for each child, get that child and it's children somehow (recursive call). Return each of those elements one at a time. It looks a inefficient because of the doubly nested loops but in reality it visits every control in the tree exactly once.

Here is how you might use it:

var buttons = ControlExt.GetAll(Page, c => c is Button);
foreach (Button button in buttons)
button.Enabled = false;

This piece of code disabled every button on the page. There are a few operations that I need to do all the time so I added in these as well:

public static IEnumerable<Control> GetAll(this Control root, Predicate<Control> test)
foreach (var item in root.GetAll())
if (test(item))
yield return item;

public static IEnumerable<T> GetAll<T>(this Control root) where T : Control
foreach (var item in root.GetAll(c => c is T))
yield return item as T;

If you have access to LINQ you probably don't need these but I am in .NET 2.0 land at the moment.

Be warned that this stuff is very easy to abuse. It allows you to make sweeping changes in a way that is difficult to track. That being said, it can be a life-saver when you need it. Have fun!

Posted by: Mike Minutillo
Last revised: 27 May, 2011 02:42 PM History


No comments yet. Be the first!

No new comments are allowed on this post.