How to hide a content place holder in a .aspx page? - asp.net

My master page has 3 content place holders:
1. left side bar
2. middle content area
3. right side bar
So it looks like:
<div id="left"></div>
<div id="content"></div>
<div id="right"></div>
On a particular view page (.aspx) that inherits the master page, I want to now show #3 (right side bar).
So I don't want the to be rendered at all.
How can I do this?

Another thing to consider is nested master pages. I have a similar design layout I'm doing in a current project, and we have a "base" master page that does all of our script includes, header and footer, and has just a single ContentPlaceHolder that represents everything between the header and footer. We then have a nested master page that uses the base master page, but adds a right "aside" column. For pages where we want the right column visible, we use the nested master page. For pages where we don't want it rendered, we use the base master page.
A strategy like this would definitely prevent your column #3 from being rendered at all (as opposed to being rendered and just being empty, which might not achieve the layout you're going for).
It looks something like this:
Base master page:
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="MasterBase.Master.cs" Inherits="MasterBase" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
...
<asp:ContentPlaceHolder ID="head" runat="server" />
</head>
<body>
<form id="form1" runat="server">
<!-- HEADER -->
...
<!-- CONTENT -->
<asp:ContentPlaceHolder ID="bodyContent" runat="server" />
<!-- FOOTER -->
...
</form>
</body>
</html>
Nested Master Page
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<asp:ContentPlaceHolder ID="head" runat="server" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="bodyContent" runat="server">
<!-- CENTER COLUMN -->
<div id="centerCol">
<asp:ContentPlaceHolder ID="bodyContent" runat="server" />
</div>
<!-- RIGHT COLUMN -->
<div id="rightCol">
<asp:ContentPlaceHolder ID="rightColumn" runat="server" />
</div>
</asp:Content>

There's a few ways you can achieve this depending on what you mean by "render".
One way is to apply an id to each page's body tag and then use CSS to hide the divs you don't want to be 'rendered' using something like
#myPage #right{display:none;}
Alternatively, if by 'render' you mean output in the HTML response then you could replace your divs with a partial view. At run time you could then decide which partial views to include in your page, either as part of a base controller that all controllers inherit or as part of each controller individually.
Using a base controller is one of the ways I replicate general code in a similar way as you might have done in a master pages codebehind in webforms.

It would be best if you used the content place holders for formatting and placed the actual content inside the .aspx files that inherit from the .master page.
This way you assign your 3 column divs in you master without content but float them left or however you want to format them with your css and use the content reference in your .aspx to place the content into the desired column.
PS. if your looking to create 3 column layout I would suggest using jquerys .ui-layout plug-in instead of trying faux columns, etc..

As per the documentation from System.Web.UI.WebControls, you can use the Visible property of the ContentPlaceHolder class.
To do this, you need to go to the CodeBehind file for the webpage. For example:
Child.aspx
<asp:ContentPlaceHolder id="HideMe" runat="server">
....
</asp:ContentPlaceHolder>
Child.aspx.vb
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
HideMe.Visible = false
End Sub
Alternatively, and as pointed out by Jamie Dixon, you can also hide the div with the css rule display:none;

Master Page
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
....
</asp:ContentPlaceHolder>
<asp:Panel ID="PanelRightMenu" runat="server">
<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
....
</asp:ContentPlaceHolder>
</asp:Panel>
Child Page code binding
this.Master.FindControl("PanelRightMenu").Visible = false;

Related

Umbraco Nested Masterpages

I'm trying to create nested master pages in Umbraco 4.7.1 and I'm having issues.
I've got a masterpage doctype and an index doctype which is a child of masterpage.
Then I have a separate doctype called slide show.
My content looks like this:
Index
SlideShow
My master page template has the reference to the index like this:
<asp:ContentPlaceHolder ID="Content" runat="server" />
then inside the index my code is between
<asp:Content ContentPlaceHolderID="Content" runat="server">
</asp:Content>
and inside the Index template I reference the next level which is an Image slider
<asp:ContentPlaceHolder ID="SlideShow" runat="server" />
and the SlideShow template has code between
<asp:Content ContentPlaceHolderID="SlideShow" runat="server">
</asp:Content>
It worked for the Index but not for the slideshow.
The only difference I can think of off hand is the doctype for index is actually a child doctype of the master. And the SlideShow doctype is actually it's own doctype. Not a child of any of them.
Any ideas how to get this working?
Having nested pages inside Umbraco is perfectly fine. In fact, it's actually an ASP.Net mechanism which doesn't necessarily relate to any heirachy in Umbraco. So it's possible to have unique Umbraco document types which don't inherit from each other, yet one master template is nested in the other.
Master templates work in a way where a master doesn't specify which templates inherit from it, it's always the child template referring to the master template, much like inheritence in object orientated programming languages. The <asp:Content /> tag in the child specifies which <asp:ContentPlaceHolder /> it uses from the parent.
I'm a bit confused how you've setup the master templates from the description, but you should try to have it setup like the following ...
Root Master Template:
<asp:ContentPlaceHolder ID="Content" runat="server" />
Index Master Template:
<asp:Content ContentPlaceHolderID="Content" runat="server">
<!-- your html -->
<asp:ContentPlaceHolder ID="IndexLeft" runat="server" />
<!-- your html -->
<asp:ContentPlaceHolder ID="IndexRight" runat="server" />
<!-- your html -->
</asp:Content>
Slide Show Master Template:
<asp:Content ContentPlaceHolderID="IndexLeft" runat="server">
<!-- your html -->
</asp:Content>
<asp:Content ContentPlaceHolderID="IndexRight" runat="server">
<!-- your html -->
</asp:Content>
You can create as many nested templates as you want, sanity-permitting. Making a document type use the template Index won't include the slide show. You'd need to give it the Slide Show template instead.
There's more info on it here: http://msdn.microsoft.com/en-us/library/ie/x2b3ktt7.aspx
Hope it helps.

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)

I am trying to add a panel as a child control of another panel in the codebehind of a master page, it's a simple as:
Panel1.Controls.Add(Panel2)
However when I try to do that, I get this error:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
There are a number of questions that talk about having <%= %> elements in the head section, which I do not have. I have been so far as to remove all <% %> elements from this page, to no avail, the error still occurs. Can anyone suggest a way to get this to work?
* Example for Answer B *
=== code with error ===
<script type="text/javascript">
jQuery(document).ready(
function() {
alert('Hello!');
jQuery("#<%=TxtSampleId.ClientID %>").focus();
}
);
</script>
=== code without error ===
<asp:PlaceHolder id="dontCare" runat="server">
<script type="text/javascript">
jQuery(document).ready(
function() {
alert('Hello!');
jQuery("#<%=TxtSampleId.ClientID %>").focus();
}
);
</script>
</asp:PlaceHolder>
The "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)." error can be very annoying to say the least. It's a bug that Microsoft refuses to fix because there are workarounds. It happens when you try to dynamically load controls from the code behind, but your page source conflicts. Could be a few things going on...
Note: Stack Overflow doesn't handle syntax of code examples well, so I'll reference each answer with a letter, and in a later post, I'll attempt to type out an example. But I don't want to clutter this post because I want to get my points across.
A.) you have a <% Response.Write("something") %> in your page source. Or a <% CodeBehindMethod() %>. Remove it and be creative to populate it a different way!! One way is to place an ASP.NET Panel control (like a Panel ==> turns into a div tag when it renders to HTML) onto your page and dynamically populate the inner HTML attribute of that control. There are other ways of dealing with this.
B.) you are trying to use jQuery inside of an inline script block within your control, you will also get this. Surround the inline javascript code block with an ASP.NET PlaceHolder tag. It's that simple. If you don't, some jQuery functionality will work, but not all of it!
C.) If you are using Script Manager without a Masterpage, I'd suggest you start using a Masterpage to avoid issues later. Then use an ASP.NET ContentPlaceHolder for your head and your body tags to make customizing pages easier. When you reference your javascript files within your masterpage, and you're using Script Manager, make sure to put a Scripts tag inside your ScriptManager tag. Then inside the Scripts tag, place a ScriptReference tag with a Path of the full path of your Javascript files in there. Make sure to put a tilda and forward slash "~/" in the beginning of your path from the root of your web app. Many will put their ScriptManager tag in their control. Don't do this. Put it in your masterpage! It makes life easier.
D.) If A, B or C didn't answer your question, then I'd suggest stripping away every piece of your page and all controls in it, and add each one at a time. If you have a huge hierarchy of page and control inheritance (if your application doesn't have a Masterpage), good luck! You'll eventually figure out what caused it.
* Example for Answer C *
=== code without error ===
Masterpage code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><meta http-equiv="X-UA-Compatible" content="IE=7" />
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Stack Overflow Example</title>
<link rel="stylesheet" type="text/css" href="/style/jquery-ui-1.8.10.custom.css">
<asp:ContentPlaceHolder id="head" runat="server">
<asp:ContentPlaceHolder>
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:ScriptManager ID="anything" runat="server">
<Scripts>
<asp:ScriptReference Path="~/scripts/md5.js" />
<asp:ScriptReference Path="~/scripts/jquery-1.4.4.min.js" />
<asp:ScriptReference Path="~/scripts/jquery-ui-1.8.10.custom.min.js" />
<asp:ScriptReference Path="~/custom_crap.js" />
</Scripts>
</asp:ScriptManager>
<asp:ContentPlaceHolder id="body" runat="server">
</asp:ContentPlaceHolder>
</form>
</body>
</html>
====================================================
Page source:
<asp:Content runat="server" ID="headcontent" ContentPlaceHolderID="head">
.. place your page specific header files here (js, css, etc..)
</asp:Content>
<asp:Content runat="server" ID="bodycontent" ContentPlaceHolderID="body">
.. place your page specific body HTML or ASP.NET code here
</asp:Content>

Events only firing on specific machines but not on others

I have been trying to solve this problem for several weeks now and it is getting really frustrating. Basically i have a simple project which includes one master page and one content page. the following code is what is found in the content page
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:Button ID="Button1" runat="server" Text="ButtonContent"
onclick="Button1_Click" />
</asp:Content>
The button is bound to a simple event. A break point is set to detect whether the event fired as expected. The event does not fire when a form is placed above the content place holder.
<%# Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<form></form>
</div>
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
<div>
</div>
</form>
</body>
</html>
however the event is fired when the form is removed or place below the content place holder. On the other hand, on some machines i have found that it does not matter if a form is placed before the content place holder. I have tried this project on 4 machines (three windows 7 and one xp) it has worked regardless of form placement on two machines and has been subject to form placement on the other two.
Could some one please point me to some setting which could solve this problem or offer any advice to solve my problem. I need a form before the content place holder so removing is out of the question. It would also make sense that some sort of setting is preventing the project from working correctly on another machine
per HTML spec, you can not have form inside form. If I remember correctly some browsers break when you have this kind of structure. I think IE works fine.
If you need another form, put it outside of the <form id="form1" runat="server">
- above it, specifically. That is valid.

Is there a simple way to have multiple ContentPlaceHolder controls update independently of each other?

This is a very simple ASP.NET master page example. The master page displays 4 hyperlinks and has two ContentPlaceholder controls. The first two links are to content pages that will display in ContentPlaceHolder1, the second two links are to content pages that will display in ContentPlaceHolder2.
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="ProofOfConcept.Site1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Demo site
</h1>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/HeadContent1.aspx">Head Content 1 in ContentPlaceHolder1</asp:HyperLink>
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="~/HeadContent2.aspx">Head Content 2 in ContentPlaceHolder1</asp:HyperLink>
<asp:HyperLink ID="HyperLink3" runat="server" NavigateUrl="~/MainContent1.aspx">Main Content 1 in ContentPlaceHolder2</asp:HyperLink>
<asp:HyperLink ID="HyperLink4" runat="server" NavigateUrl="~/MainContent2.aspx">Main Content 2 in ContentPlaceHolder2</asp:HyperLink>
<br />
<div style="border: 1px dotted blue;">
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
This is default text for ContentPlaceholder1
</asp:ContentPlaceHolder>
</div>
<br />
<div style="border: 1px dotted red;">
<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
This is default text for ContentPlaceholder2
</asp:ContentPlaceHolder>
</div>
</div>
</form>
</body>
</html>
The four content pages themselves all look like this:
<%# Page Title="" Language="C#" MasterPageFile="~/Site1.master" AutoEventWireup="true" CodeBehind="MainContent1.aspx.cs" Inherits="ProofOfConcept.MainContent1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceholder2" runat="server">
This is text from MainContent1 in ContentPlaceholder2
</asp:Content>
...with the ContentPlaceholder ID setas appropriate. In other words, each content page only contains one Content control linked to the one of the ContentPlaceHolders on the Master page.
If I build the site and load HeadContent1.aspx (the first link), for instance, only the content from HeadContent1 is displayed (plus markup from the master page, obviously). If I click the third link, content in the second ContentPlaceHolder is displayed, but the first Placeholder reverts to its default markup.
This behaviour all appears to be as designed and is undoubtedly very useful in many scenarios, but what I'd like to do is have the two ContentPlaceholders refresh independently of each other. To work like old-fashioned HTML frames, more or less? Is this possible, or should I be using some other control (or a different setup instead of Master/Content)?
I would say you want to use iframes for your situation. Master pages don't function the way you are looking for.
I agree with Mike. You are going the long way around. In order for your example to work with Master Pages, you will need 16 different content pages. Each page would need to fill the content for PlaceHolder1 and PlaceHolder2 depending on which links were clicked and in what order.
An IFrame would be a better way to handle something like this, but I would first recommend you review your design to determine if there is a way that it can be simplified.

Asp.net Masterpage not working

<%# Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet" type="text/css" href="Home.css" />
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
<div id="banner" style="font-family: Calibri, Serif; color: #FFFFFF">
blah blah
</div>
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
Home.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Home.aspx.cs" Inherits="Home"
MasterPageFile="~/MasterPage.master" Title="Welcome to StuartStudios!"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
</asp:Content>
Does Home.aspx not print whatever I define in the ContentPlaceHolder1 ? At the minute it prints nothing out. :S
When you specify markup in a ContentPlaceHolder inside of a MasterPage, that markup will only be rendered if the pages that use your master pages don't use the ContentPlaceHolder. So in Home.aspx, if you get rid of the Contact1 element, you should see your "banner" div.
So if you want your banner div to appear on ALL pages, you should move it to outside the ContentPlaceHolder control.
On your individual pages that use your master page, the Content tag should contain the stuff that's unique to the specific page.
No... ContentPlaceholder1 should be left blank in the masterpage.
I am no expert in ASP.Net, but as far as I understand the way <asp:ContentPlaceHolder /> works, when you add a <asp:Content> tag in your page file, you override the content of the ContentPlaceHolder in the master page. The contents of which will only be displayed if you do not have a corresponding Content tag.
Two things I see:
Your div in your master page has color set to white. So unless I'm mistaken, you're printing white on white.
Your Content item in Home.aspx IS empty, so why would it print anything else?

Resources