views:

42

answers:

3

I need to get the list of ContentPlaceHolders of a MasterPage, but the property

protected internal IList ContentPlaceHolders { get; }

is protected internal, so we can't access them.

Is there any way we could pull them up from the MasterPage (including Reflection)? Thanks.

+2  A: 

When you don't mind using reflection and don't mind the risk of your application breaking when migrating to a newer version of .NET, this will work:

IList placeholderNames =
    typeof(MasterPage).GetProperty("ContentPlaceHolders", 
        BindingFlags.Instance | BindingFlags.NonPublic)
    .GetValue(myMasterPage, null) as IList;
Steven
Thanks for the warning too. =)
Jronny
+2  A: 

You can recursively loop through Master.Controls and check each control to see if it is of the type ContentPlaceHolder.

private readonly IList<ContentPlaceHolder> _contentPlaceHolders = new List<ContentPlaceHolder>();
private void FindContentPlaceHolders(ControlCollection controls)
{ 
    foreach(Control control in controls)
    {
        if (control is ContentPlaceHolder)
        {
            _contentPlaceHolders.Add((ContentPlaceHolder) control);
            return;
        }
        FindContentPlaceHolders(control.Controls);             
    }
}
Daniel Lee
This is less risky than Reflection though. Maybe Master.Controls.Cast<Control>().Where(a => a is ContentPlaceHolder) .Select(a => (ContentPlaceHolder)a) will also work. =)
Jronny
I tried but am very unfortunate it does not work. =(
Jronny
I tested it out on an old webforms project (.NET 3.5) with a masterpage with two ContentPlaceHolders and it worked for me. I passed Master.Controls into the FindContentPlaceHolders method. I noticed that the ContentPlaceHolders were not directly contained in the Master.Controls collection. They were nested further down in the hierarchy.
Daniel Lee
+1  A: 

As a variation to the answer of Daniel, you can write that as an extension method on MasterPage:

public static IEnumerable<ContentPlaceHolder>
    GetContentPlaceHolders(this MasterPage master)
{
    return GetAllControlsInHierarchy(master)
        .OfType<ContentPlaceHolder>();
}

private static IEnumerable<Control> GetAllControlsInHierarchy(
    Control control)
{
    foreach (var childControl in control.Controls)
    {
        yield return childControl;

        foreach (var childControl in
            GetAllControlsInHierarchy(childCOntrol))
        {
            yield return childControl;
        }
    }
}
Steven