
Introduction
After moving to .NET, I was building a simple website that would have four or
five pages of content, but they should all have the same look. In the past, I
would build a template page with the look I desired and build HTML pages for the
each page of content. The content pages would be plain HTML and I would use a
method to include them into the content area of the main template page depending
on the currently selected page.
Now that I was working with .NET, I started to research ways I could
accomplish the same task. While I could use similar methods as I used in earlier
sites, the Web User Controls seemed to be a better way to handle embedding
content from one file into another.
I quickly threw together several user controls filled with content and built
my main page with a blank area for the content. At this time point I was stuck.
Now that I had the user controls and could drop them on the page, I needed an
easy method to switch between them depending on which page of content was to be
displayed.
After a bit more research, I decided to build a web control that would render
the desired user control and act as a placeholder. While I was at it, I decided
to make it even more useful and added the ability to specify a URL parameter
that it could read to select the user control without having to keep track of
the content page. Thus this control was born.
Demos
I have built three demos that are all the same format, but each uses this
control in different methods. They all appear as the example picture above.
ContentPanelSiteOne:
This demo shows the basic functionality of this control. The entire page
other than the white content panel (where it says "Home .. Content Page") is in
Core.aspx. The content panel is the RJContentPanel
control. The default user
control is the "Home" which is shown when you first go to the site.
A live demo can be found at:
http://GotTheAnswerToSpam.com/ContentPanelSiteOne/Core.aspx.
In the "Controls" folder, there are Home, Products, FAQ and Contact Us user
controls. When you first go to the site, the RJContentPanel
control defaults to
"Home", which is the user control shown in the white area of the page. When you
click on the Products link, you will notice that the content area changes and so
does the URL. Now it is "Core.aspx?P=Products". That tells the RJContentPanel
to
display the user control "Products.ascx" (the control appends the ".ascx"
extension). Same goes for the other links, where "P=" is set to the user control
to display.
This makes it easy to build a multi page site and use a template where only
the content changes. You simply drop this on the form you use as a template, set
the path to the controls (in this case "Controls/" ), set the default page (in
this case "Home") and set the RequestVariable
Property to "P". At that point, it
is ready to go.
Example sites that use this is:
and
ContentPanelSiteTwo:
This will appear the same as site one, however now, you will not see the
parameters when you click on the links. The links post back and in the code, it
sets the default page of the RJContentPanel
directly and forces the page to
rebuild. In the code behind there is:
private void LinkButton1_Click(object sender, System.EventArgs e)
{
RJContentPanel1.DefaultPage="Home";
RJContentPanel1.ForceBuildControlsNow();
}
This method allows the template page to be the only item in the URL without
the need for parameters. There are drawback though, as a person cannot save a
link to an individual page since it will only point to the Core.aspx file.
Live Demo Link:
http://GotTheAnswerToSpam.com/ContentPanelSiteTwo/Core.aspx.
ContentPanelSiteThree:
The first thing you will notice, we now use a different name for the page,
instead of going to Core.aspx, we go to Home.aspx. This is just a trick however.
The site is similar to ContentPanelSiteTwo, but this one uses dummy pages for
navigation. There is now a page for each link and each page contains two lines
of code:
HttpContext.Current.Items["TargetPage"]="Home";
Server.Transfer("Core.aspx");
The first line sets a value in the current context Items collection. This
value only exists for the duration of the request and can be an easy method to
pass data between modules that make up the page. In this case, the value is set
to the page our home.aspx page refers to and then transfers control to our
normal Core.aspx file. You will find in the Core.aspx file in the OnInit method,
it looks for the "TargetPage
" item in the current context's item collection and
set the RJContentPanel's
DefaultPage
to the value it contains.
All the pages are built the same way, only the TargetPage
name is changed.
Makes it very quick to build a number of these files.
Why use both a web form page and a web user control for the content? This
makes it easier for some search engines to index your site and some people might
find the names friendlier than parameters on the URL.
This does come with a bug though. The Contact Us page on all the demos simple
prompts for a name and once entered and you click the submit button, it performs
a Response.Write
out to the top of the page. Nothing fancy, but it is there to
show the action.
In this demo, if you click on the submit button, the page in the URL changes.
This is due to a feature (bug to me) in the forms processing in ASP.NET. There
is a simple method around it. You can replace your HtmlForm
with:
using System;
using System.Web;
using System.Web.UI;
namespace ActionlessForm
{
public class Form : System.Web.UI.HtmlControls.HtmlForm
{
protected override void RenderAttributes(HtmlTextWriter writer)
{
writer.WriteAttribute("name", this.Name);
base.Attributes.Remove("name");
writer.WriteAttribute("method", this.Method);
base.Attributes.Remove("method");
this.Attributes.Render(writer);
base.Attributes.Remove("action");
if (base.ID != null)
writer.WriteAttribute("id", base.ClientID);
}
}
}
This I found this while looking at URL rewriting at:
http://msdn.microsoft.com/asp.net/using/building/web/default.aspx?pull=/library/en-us/dnaspp/html/URLRewriting.asp
Live Demo Link:
http://GotTheAnswerToSpam.com/ContentPanelSiteThree/Home.aspx.
Usage
Using the control is simple. Just drop the control on your form and set the
following three Properties:
RequestVariable:
If you wish to use the method in ContentPanelSiteOne where it tracks the
content page based on a URL parameter, you would set this to the name of that
parameter. In the demo it was set to "P".
DefaultPage:
This is the page that will be displayed if there is either no RequestVariable
set or it has no value. If you are not using the URL parameter method, this will
be the value you set to switch content controls.
ControlFolder:
Set this to the virtual path (not physical) of the folder were you user
controls are stored. In the demos this was set to "Controls/".
Methods
ForceBuildControlsNow()
This is the only method Added. You would use this if the form is already
created and you wish to switch to another user control. There are also times
when you might want to access controls in the user control from the host page
and want to ensure the that user control is created.
Conclusion
The control itself is quite simple and surprisingly requires very little code
to perform this task. At this point, there is still one problem I would like to
find a way around. When you have graphics in your user control that is displayed
via this control, you will have to use the full path. It does not path properly
to the images. This only happens if the graphics are located in the folder with
your controls or under them.
** IF YOU FIND THIS USEFUL, you are encouraged to stop by
www.HintsAndTips.com and share a few tips that you have discovered. Member ship
is free. The tips do not have to be on programming, they can be on almost any
topic.
Version History:
1.0.1599.2341 - May 18, 2004
- General clean up of code
- Added saving of settings to
ViewState
- Removed the requirement to end the
ControlFolder
path
name with a "\"
1.0.1512.38470 -
February 21, 2004
Most recent sources can always be found at
www.RJSoft.com/Products/