views:

193

answers:

3

Well I'm some what baffled!

'Simple problem'

I have parts of my master page that I want to render differently depending on whether or not a ContentPlaceHolder is empty.

So:

I have a master page that as some code like:

<% if (ContentPlaceHolder1.HasControls()) {%>
    <div id="LittleDiv">
<% } else { %>
    <div id="BigDiv">
<% } %>
        some text
    </div>

<% if (ContentPlaceHolder1.HasControls()) {%>
    <div id="Div1">
         yadda yadda yadda
         [<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"/>]
         blah blah blah
    </div>
<% } %>

I have a page that has some code along the lines of:

<asp:Content ID="Content1" runat="server" contentplaceholderid="ContentPlaceHolder1">
   <% if (Model.SomeValue) { %>
       hello! 
   <% } %>
</asp:Content>

(note: the logic in the example page's embeded code block may be unique, for each content place holder, for each page!)

Which seems nice however it doesn't work. The problem is as I see it (warning I might be completely wrong!). The Embedded Code Blocks are evaluated in the objects Render. A little counter intuitively the page seems to control the master. So the master page's Render is called before the pages render. This means that the master page always sees content in the page's content control.

Is there a nice way round this? (I have a bit of a solution but it is a monstrous hack! I won't post it yet coz I don't want to influence thinking.)

A: 

Rather than looking for the resultant controls can your master page examine the contents of the ViewData dictionary and work its logic from there?

Chris Arnold
Wilfred Knievel
Not sure you can do this as your master page will not have access to any 'concrete' page Model objects (assuming that's what you meant by forcing the model to implement an interface?).
Chris Arnold
A: 

Alternatively, you could use javascript to show / hide divs on the client.

Chris Arnold
Yeah very good point, unfortunately I should have said I was looking for a server side solution. Mind you if I can't find a good solution this will probably be the final approach!
Wilfred Knievel
+1  A: 

OK, here's another idea :). Instead of putting the logic in your master page...

<% if (ContentPlaceHolder1.HasControls()) {%>
    <div id="LittleDiv">
<% } else { %>
    <div id="BigDiv">
<% } %>
        some text
    </div>

Why not create a placeholder for it? e.g.

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

You could then allow your concrete non-master pages to decide the content. You could also avoid repeating yourself by moving the logic into a Partial View that could be, say, parameterised by your different views.

Chris Arnold