views:

824

answers:

2

I have a master page with a content control. I want it to do something specific during load if a particular content place holder has been used.

APageWithContent.aspx

<asp:Content ContentPlaceHolderID="myContent" runat="server">
    <div>hello world!</div>
</asp:Content>

MasterPage.aspx

<asp:ContentPlaceHolder ID="myContent" runat="server" />

It's optional on the pages that use the master whether they provide any content for this placeholder.

I want to be able to tell during the load and prerender events in the master page whether there is a content for my placeholder on the current page.

MasterPage.aspx.cs

void Page_Init( object sender, EventArgs e )
{
    if( /* myContent is populated */ )
        //do something
}

Anyone know how to discern this?

In WebForms you can check the controls:

myContent.Controls.Count > 0

But for MVC views this always appears to be 0.

+2  A: 

I did this by just checking myContent.Controls.Count.. However, you obviously need to take into consideration any default controls that might be added.

For example, if you have your content placeholder defined as:

<asp:ContentPlaceHolder ID="myContent" runat="server">
</asp:ContentPlaceHolder>

Then you will get a LiteralControl in the controls collection containing "\r\n" (since the line break in the definition is parsed).

So, if you remove that and define as:

<asp:ContentPlaceHolder ID="myContent" runat="server"></asp:ContentPlaceHolder>

Then you can do the check in the master page load:

if (myContent.Controls.Count > 0)
// do stuff when populated with content..

Just make sure you test the code to make sure you are actually checking for content added by the content pages, and not any default content defined in the master.

UPDATE

Following edit saying this problem is MVC-only I can confirm I am unable to replicate. I used the same code as above in an MVC app and it worked exactly as expected & described.

Can you post some sample code of what you have in place?

FYI - Here is the [working] code:

Site.Master

<asp:ContentPlaceHolder ID="myContent" runat="server"></asp:ContentPlaceHolder>

<% if (myContent.Controls.Count > 0) { %>
    <b>Content Added!</b>
<% } %>

Index.aspx

<asp:Content ContentPlaceHolderID="myContent" ID="myContent" runat="server">
This will render and the "Content Added!" will also be rendered.
</asp:Content>

<%-- This will cause the "Content Added!" to be displayed but with no visual content --%>
<asp:Content ContentPlaceHolderID="myContent" ID="myContent" runat="server">
</asp:Content>

<%-- This will NOT render the "Content Added!" since there is zero content between tags --%>
<asp:Content ContentPlaceHolderID="myContent" ID="myContent" runat="server"></asp:Content>
Rob Cooper
Hrm, that's odd. I have an app with legacy WebForms and MVC content, and they both use the same master page. The MVC content in the page is relatively simple - lots of <%= %> blocks. In my WebForms pages myContent.Controls.Count is right, in my MVC pages it seems to always be 0.
Keith
Thanks for the clarification and the check (+1 and acc). I think my problem here must be something FUBAR with the combined project - something for another question.
Keith
I can now reproduce and have asked as a new question: http://stackoverflow.com/questions/964724
Keith
A: 

Must check if there any controls in Holder which type is not LiteralControl

private bool GetVisible { get { foreach (Control ctrl in cphAdminMenu.Controls) { if(!ctrl.GetType().ToString().Contains("LiteralControl")) return true; } return false; } }

myControl.Visible = GetVisible;

NicK
This went on to another question: http://stackoverflow.com/questions/964724
Keith