I know this is an old post, and I really liked christian libardo's solution. However, I do not like the  fact that in order to yield an entire set of elements to the outer scope I would have to iterate over those elements yet again only to yield those to myself from an inner scope to the current scope. I prefer:
IEnumerable<Control> getCtls(Control par)
{    
    List<Control> ret = new List<Control>();
    foreach (Control c in par.Controls)
    {
        ret.Add(c);
        ret.AddRange(getCtls(c));
    }
    return (IEnumerable<Control>)ret;
}
Which allows me to use it like so:
foreach (Button but in getCtls(Page).OfType<Button>())
{
    //disable the button
    but.Enabled = false;
}