Click here to Skip to main content
Click here to Skip to main content

ASP.NET Page Templates - Using Inheritance

By , 19 Sep 2002
Rate this:
Please Sign up or sign in to vote.

Page Inheritance Class Diagram

Introduction

Anyone who has developed commercial websites has run into the problem of creating a template for the site. For most sites a large percentage of the HTML is the same or similar for all pages. The header, navigation, and footer elements of a typical site layout appear on almost every page.

Some developers will put that markup in every page's source file. Anyone who's had to maintain a site put together this way knows how difficult it is to make site-wide changes. You end up depending on massive search and replace operations, which can be difficult to do without creating markup errors that require hand-tuning to repair.

In traditional ASP programming, like many other server-based programming environments, this was typically solved using an include file. The page is divided into logical sections representing the header, left navigation, body, and footer elements. A separate include is created for each of the common elements and the body section is placed in the actual ASP page. The page then includes the appropriate files to build up the look and feel of the page. This is a significant improvement over the previous approach, but still creates a few maintenance problems.

First of all, the individual ASP files must contain the code necessary to include the correct support files. This makes each page's content strongly coupled to the site's template. It also means that when you add a new page to the site, you must remember to setup all the correct includes in the right order.

An additional problem happens when you decide to make a significant look-and-feel change to the site. If you're lucky, you may be able to make all of your changes in the include files. Most of the time, however, the tight coupling between the include files and the ASP pages means that you end up having to edit each and every ASP page as well.

With the introduction of ASP.NET, developers have been giving a powerful new set of tools to help resolve these problems. ASP.NET uses an object-oriented development paradigm. In practical terms this means that every page is a class that derives from System.Web.UI.Page. This class provides a number of services to the web developer including caching, rendering, response and request access, etc.

So the question is: How can we best take advantage of the object-oriented nature of ASP.NET when creating websites? Is there a better way to create templates than using include-files?

Web User Controls

One of the first things a developer notices when getting started with ASP.NET is that a new style of control has been introduced: Web User Controls. User Controls allow a developer to encapsulate a common chunk of HTML or server-side code into a component that can be reused on many different pages.

User controls are not used in a page using the #include directive. Instead that are either placed in the ASPX file as a custom tag (with the Register directive) or from server-side code with the LoadControl statement.

This article is not going to go into the details of creating and using User Controls; there are many other sources that cover that topic. They are, however, and improvement over the old include-file approach and deserved mention here.

They don't solve all of the problems discussed above though. If, for example, you encapsulate your page header in a user control, you still have to remember to use it on each and every page in the site. If you decide you need to add another user control to another part of your site, then once again you end up editing every page to get that user control embedded.

Also, depending on the layout of the pages in your site, you may end up having some formatting or positioning markup in each page to make sure that the User Control is exactly where you want it on the page. This markup is common to every page and we should be able to find a way to have that code exist in only one place.

Simple Page Inheritance

If you're familiar with object-oriented programming then you are probably already seeing something familiar. When you have a chunk of code that occurs in more than one class, it is common practice to refactor that code by creating a base class and moving that code "up" one level in the inheritance chain. Why not do that here?

Since all ASPX pages derive from System.Web.UI.Page, we should be able to create a base class that sits between our page class and the Page class. This class will be responsible for producing the template used in our site. Then our page classes will derive from the base class and will only contain the markup and server controls needed for their specific task. To illustrate this, let's create an example base class called PageBase and then derive a page class from it. (All of the examples in this article are written in C#, but you should easily be able to convert them to VB.NET or any other .NET language.)

using System;
using System.Web.UI;
public class PageBase : System.Web.UI.Page
{
    private string _pageTitle;
    public string PageTitle
    {
        get { return _pageTitle; }
        set { _pageTitle = value; }
    }

    protected override void Render(HtmlTextWriter writer)
    {
        // First we will build up the html document, 
        // the head section and the body section.
        writer.Write( @"
            <html>
                <head>
                    <title>" + PageTitle + @"</title>
                </head>
                <body>" );

        // Then we allow the base class to render the 
        // controls contained in the ASPX file.
        base.Render( writer );

        // Finally we render the final tags to close
        // the document.
        Writer.Write( @"
                </body>
            </html>" );
    }
}

Let's take a look at a few interesting points illustrated in this base class. First of all, we expose a property called PageTitle that will contain the title for the page. This property's contents are written out in the <title> section of the page. Also notice the '@' symbol used before the string literals. While not explicitly required for this example, the '@' symbol is a C# token that says the following string literal should not have escape sequences expanded. If we didn't do this, we would have to escape our slash characters. If you are working in VB.NET you don't have to worry about this.

Now we will create an ASPX page that derives from PageBase. I'll be using code-behind pages, so we have two files. The first file has a file extension .ASPX and contains the markup for the page.

<%@ Page language="c#" Codebehind="SimplePageInheritance.aspx.cs" AutoEventWireup="false" 
       Inherits="SimplePageInheritance" %>
<form id="SimplePageInheritance" method="post" runat="server">
    <h1>This is Page 1</h1>
    <p>
        This page demonstrates Simple Page Inheritance where the content is rendered 
        using the base class' Render() method. You cannot use Server Controls that 
        postback in the base class, they can only be used in the .ASPX page itself.
    </p>
</form>

Notice that there is no markup for "standard" content like <html>, <head> and <body> because they will be rendered in the base class. The code-behind class defines the SimplePageInheritance class referenced in the Page declaration.

public class SimplePageInheritance : PageBase
{
    public SimplePageInheritance()
    {
        PageTitle = "Simple Page Inheritance";
    }
}

Pretty cool, eh? This solution solves all of the problems with include-based templates mentioned earlier. For some situations, however, it doesn't solve everything. For those we need Advanced Page Inheritance.

Advanced Page Inheritance

The biggest problem with the Simple Page Inheritance system is that you cannot put any server controls that cause a post-back in the template base class. The reason for this is related to the position of the <form> tag. In Simple Page Inheritance, the <form> tag is included in the derived ASPX page. Therefore any markup rendered by the base class will be either before or after the ASPX file markup. This might occur if, for example, we wanted a search system included in the template.

There are many different ways we could solve this problem. For this example, we will move the <form> tag from the ASPX file to the base class. We can't just render the <form> tag as a string literal either, because in ASPX files, the form is actually processed on the server before the markup is sent to the browser. So we have to create a Form object and insert it into the Controls collection of the page.

using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;    
public class AdvancedPageInheritanceBase : System.Web.UI.Page
{
    protected override void OnInit(System.EventArgs e)
    {
        BuildPage( GenerateHtmlForm() );
        base.OnInit(e);
    }

    protected void BuildPage( HtmlForm form )
    {
        ////////////////////////////////////////////////////////
        // Build the page and include the generated form

        this.Controls.AddAt( 0, new LiteralControl( @"
            <html>
                <head>
                    <title>" + PageTitle + @"</title>
                </head>
                <body>
            ") );

        this.Controls.Add( form );

        this.Controls.Add( new LiteralControl( @"
                </body>
            </html>
        "));
    }

    private HtmlForm GenerateHtmlForm()
    {
        HtmlForm form = new HtmlForm();
        AddSearch(form);
        AddControlsFromDerivedPage(form);
        return form;
    }

    private void AddSearch( HtmlForm form )
    {
        searchBox = new TextBox();
        Button searchButton = new Button();
        searchButton.Text = "Search";
        searchButton.Click += 
            new EventHandler( this.OnSearchButtonClicked );
        form.Controls.Add( searchBox );
        form.Controls.Add( searchButton );
        form.Controls.Add( new LiteralControl("<br>") );
    }

    protected void OnSearchClick( object sender, EventArgs e )
    {
        // Do the search here
    }

    private void AddControlsFromDerivedPage(HtmlForm form)
    {
        int count = this.Controls.Count;
        for( int i = 0; i<count; ++i )
        {
            System.Web.UI.Control ctrl  = this.Controls[0];
            form.Controls.Add( ctrl );
            this.Controls.Remove( ctrl );
        }
    }
}

Remember that I said there are many ways to solve the <form> tag placement problem. In this solution we create an HtmlForm control, populate it with the contents of the ASPX page and then insert it into the template.

This system works very well and allows us to create ASPX pages that are completely independent of the template. Here is the ASPX file:

<%@ Page language="c#" Codebehind="AdvancedPageInheritance.aspx.cs" 
            AutoEventWireup="false" 
       Inherits="PageInheritanceSample.AdvancedPageInheritance" %>
<h1>Advanced Page Inheritance</h1>
<p>This demonstrates the Advanced Page Inheritance Technique.</p>

The code-behind file is no different than the one used in the Simple Page Inheritance example. Notice that our ASPX file doesn't have a <form> tag in it.

Performance

I was surprised to find that there is almost no performance difference when using page inheritance. Using Microsoft Application Center Test, I ran page load tests on three different versions of similar page structures:

  • The first page used user controls to encapsulate the header, left navigation and footer sections. It did not use any page inheritance.
  • The second page had the same look & feel and the same content but used the method outlined in Simple Page Inheritance.
  • The third page had a similar look & feel (it included a search box like in the example code) and used the method outlined in Advanced Page Inheritance.

The following table shows the results after loading each page continuously for 5 minutes on my development workstation. As you can see, the differences are minimal.

Page # of Requests Avg. Response Time (ms) Avg. Requests per Sec.
WebUserControl.aspx 16,693 10.53 55.64
SimplePageInheritance.aspx 16,636 10.54 55.45
AdvancedPageInheritance.aspx 16,965 10.20 56.55

Conclusion

Developing websites and web applications that are easy to maintain has always been a challenge. Over time the techniques used have evolved from almost nothing to modern object-oriented techniques like those presented in this article. These techniques can be used by anyone with a basic understanding of object-oriented programming and will almost certainly help you produce better factored, easier to maintain code.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Peter Provost
Web Developer
United States United States
Peter Provost has been programming computers since he was 10 years old. Currently a C# and C++ junkie, he has been developing on the Windows platform since Windows 286.
 
Peter is a Software Design Engineer with Microsoft's patterns and practices team where he works on guidance for .NET developers.
 
Peter maintains an active weblog about technology, .NET and other interesting stuff at http://www.peterprovost.org

Comments and Discussions

 
GeneralRe: UserControls with html-code dont work! PinmemberLynxRaven10-Feb-05 18:25 
GeneralButtons in asp .net PinsussXimena Uchupanta30-Sep-04 6:17 
GeneralRe: Buttons in asp .net PinmemberAmitSeth7-Feb-05 19:32 
GeneralPositioning Controls Pinmemberbluntedj21-Aug-04 2:44 
GeneralRe: Positioning Controls PinmemberSpiff Dog25-Sep-04 14:44 
QuestionSample AdvancedPageInheritance code in VB? Pinmemberdstein2213-Aug-04 7:56 
AnswerRe: Sample AdvancedPageInheritance code in VB? PinmemberSpiff Dog23-Aug-04 11:33 
GeneralAdvancedPageInheritance code in VB not working...PLEASE HELP! Pinmemberbretonk24-Sep-04 2:35 
Please help. I've attempted about 10 different template techniques which have all failed. This <i>seems</i> to be the best solution. However, I cannot get the class to properly work when I inherit from the BaseForm class and place server controls on the derived page.
 
The following code, which also has a SiteNavigation class, is my attempt at implementing the C# version of the advanced inheritance class using VB.
 
<b>BaseForm.vb</b>
 
<code>Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls
Imports web.SiteNavigation
 
Public Class BaseForm
      Inherits System.Web.UI.Page
 
#Region "         Variable Declarations"
      'Layout Settings
            Const BODY_BGCOLOR As String = "#004080"
            Const StyleSheet As String = "Include/QARS.css"
 
            Private _PageTitle As String
            Protected plhTopNav As PlaceHolder
            Protected plhLeftNav As PlaceHolder
            Private myForm As HtmlForm
 

      'Navigation
            Protected SiteNavigation As web.SiteNavigation
            Private _SiteNavigationParentIX As Integer 'indicates which parent nav item is selected -- if any
 
      'Security
            Private _UserTypeID As Integer
#End Region
#Region "         Properties"
 
      Public Property SiteNavigationParentIX()
            Get
                  Return _SiteNavigationParentIX
            End Get
            Set(ByVal Value)
                  SiteNavigationParentIX = _SiteNavigationParentIX
            End Set
      End Property
      Public Property UserTypeID() As Integer
            Get
                  Return _UserTypeID
            End Get
            Set(ByVal Value As Integer)
                  _UserTypeID = Value
            End Set
      End Property
      Public Property PageTitle()
            Get
                  Return _PageTitle
            End Get
            Set(ByVal Value)
                  _PageTitle = PageTitle
            End Set
      End Property
 
#End Region
      Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
            'Create instance of Site Navigation
            BuildPage()
            MyBase.OnInit(e)
      End Sub
 
      Protected Sub BuildPage()
            'Build the page and include the generated form
            Dim allSiteNavigationItems() As SiteNavigationItem
            Dim allSubSiteNavigationItems() As SiteNavigationItem
            Dim currSiteNavItemIX As Integer
            Dim newPlaceHolder As PlaceHolder
            Dim iCurrControlNum As Integer = 0
 
            myForm = New HtmlForm
 

            'Start building Form Contents
                  myForm.Controls.AddAt(iCurrControlNum, New LiteralControl( _
                        "         <TABLE border=1 width=100%>" & vbCrLf & _
                        "               <TR>" & vbCrLf & _
                        "                     <TD colspan=3>" & vbCrLf & _
                        "                     <TABLE>" & vbCrLf & _
                        "                           <TR>" & vbCrLf & _
                        "                                 <TD><img src=" & ChrW(34) & "Images/sm_PennDot.jpg" & ChrW(34) & "></TD>" & vbCrLf & _
                        "                                 <TD width=100%></TD>" & vbCrLf))
                        iCurrControlNum += 1
 
            'Create Top Nav
                              'Start the cell
                                    myForm.Controls.AddAt(iCurrControlNum, New LiteralControl("                                 <TD>" & vbCrLf))
                                          iCurrControlNum += 1
 
                              'Create Top Nav placeholder
                                    newPlaceHolder = New PlaceHolder
                                    newPlaceHolder.ID = "plhTopNav"
                                          plhTopNav = newPlaceHolder
 
                                    myForm.Controls.AddAt(iCurrControlNum, newPlaceHolder)
                                          iCurrControlNum += 1
 
                              'Close the Cell
                                    myForm.Controls.AddAt(iCurrControlNum, New LiteralControl("</TD>" & vbCrLf))
                                          iCurrControlNum += 1
 
            'Close the Top Nav
                  myForm.Controls.AddAt(iCurrControlNum, New LiteralControl( _
                        "                           </TR>" & vbCrLf & _
                        "                     </TABLE>" & vbCrLf & _
                        "                     </TD>" & vbCrLf & _
                        "               </TR>"))
                        iCurrControlNum += 1
 
            'Start 2nd Row -- Left Nav & Content
                  myForm.Controls.AddAt(iCurrControlNum, New LiteralControl( _
                        "               <TR>" & vbCrLf & _
                        "                     <TD>" & vbCrLf & _
                        "                     <TABLE>" & vbCrLf))
                        iCurrControlNum += 1
 
            'Create side Nav
                              'Start the cell
                                    myForm.Controls.AddAt(iCurrControlNum, New LiteralControl("<TR><TD>"))
                                          iCurrControlNum += 1
 
                              'Create Left Nav Placeholder
                                    newPlaceHolder = New PlaceHolder
                                    newPlaceHolder.ID = "plhLeftNav"
                                          plhLeftNav = newPlaceHolder
                                    myForm.Controls.AddAt(iCurrControlNum, newPlaceHolder)
                                          iCurrControlNum += 1
 
                              'Close the cell
                                    myForm.Controls.AddAt(iCurrControlNum, New LiteralControl("</TD></TR>" & vbCrLf))
                                          iCurrControlNum += 1
            'Close side nav
                        myForm.Controls.AddAt(iCurrControlNum, New LiteralControl( _
                              "                     </TABLE>" & vbCrLf & _
                              "                     </TD>" & vbCrLf))
                              iCurrControlNum += 1
 
            'Get Content
                  myForm.Controls.AddAt(iCurrControlNum, New LiteralControl( _
                        "                     <TD colspan=2 bgcolor=#004080>" & vbCrLf))
                        iCurrControlNum += 1
 
                  'ADD CONTENT HERE!!!!!!!!!
                        myForm.Controls.AddAt(iCurrControlNum, Me.Controls(0))
                              iCurrControlNum += 1
 
                  myForm.Controls.Add(New LiteralControl( _
                        "                     </TD>" & vbCrLf & _
                        "                     </TR>" & vbCrLf & _
                        "         </TABLE>" & vbCrLf))
 

 
                  Me.Controls.Clear()
 
            'Start Header
                  Me.Controls.Add(New LiteralControl( _
                        "<html> " & vbCrLf & _
                        "   <head>" & vbCrLf & _
                        "         <title>" & HttpUtility.HtmlEncode(_PageTitle) & "</title>" & vbCrLf & _
                        "<link rel=" & ChrW(34) & "stylesheet" & ChrW(34) & " type=" & ChrW(34) & "text/css" & ChrW(34) & " href=" & ChrW(34) & StyleSheet & ChrW(34) & ">" & vbCrLf & _
                        "   </head>" & vbCrLf & _
                        "   <body width=800   bgcolor=" & BODY_BGCOLOR & ">" & vbCrLf))
 
            'CONTENT FORM
                  Me.Controls.Add(myForm)
 
            'FOOTER
                  Me.Controls.Add(New LiteralControl( _
                        "   </BODY>" & vbCrLf & _
                        "</HTML>"))
      End Sub
      Private Sub AddControlsFromInheritedForm(ByRef myForm As HtmlForm)
            'Copy all the existing controls from inheriting form into this structure
            Dim i As Integer
            For i = Me.Controls.Count - 1 To 0
                  myForm.Controls.Add(Me.Controls(i))
                  Me.Controls.RemoveAt(i)
            Next
      End Sub
End Class
</code>
 

 
<b>SiteNavigation.vb</b>
<code>Option Explicit On
Imports System
Imports System.Web.UI
Imports System.String
Imports Microsoft.VisualBasic
 
'This class handles navigation items as a whole
Public Class SiteNavigation
      'Stores Parent navigation
            Private SiteNavigationItems() As SiteNavigationItem
 
      'Stores Children navigation
            Private SiteNavigationSubItems() As SiteNavigationItem
 
      'Stores current navigation
            Public TopNav_Placeholder As PlaceHolder
            Public LeftNav_Placeholder As PlaceHolder
            Public Sub New(ByVal UserTypeID As Integer)
                  If UserTypeID = 3 Then
                        ReDim SiteNavigationItems(2)
                              ReDim SiteNavigationSubItems(8)
                  Else
                        ReDim SiteNavigationItems(1)
                              ReDim SiteNavigationSubItems(5)
                  End If
 
                  'Create Parent Navigation Items
                        'REPORTS
                              SiteNavigationItems(0) = New SiteNavigationItem("Reports", "reports/defaultReports.aspx", 0)
                              'Create Child Navigation Items
                                    SiteNavigationSubItems(0) = New SiteNavigationItem("Report #1", "reports/report1.aspx", 0, 0)
                                    SiteNavigationSubItems(1) = New SiteNavigationItem("Report #2", "reports/report2.aspx", 1, 0)
                                    SiteNavigationSubItems(2) = New SiteNavigationItem("Report #3", "reports/report3.aspx", 2, 0)
 
                        'REVIEWS
                              SiteNavigationItems(1) = New SiteNavigationItem("Reviews", "/reviews/defaultReviews.aspx", 1)
                              'Create Child Navigation Items
                                    SiteNavigationSubItems(3) = New SiteNavigationItem("Review #1", "reviews/review1.aspx", 3, 1)
                                    SiteNavigationSubItems(4) = New SiteNavigationItem("Review #2", "reviews/review2.aspx", 4, 1)
                                    SiteNavigationSubItems(5) = New SiteNavigationItem("Review #3", "reviews/review3.aspx", 5, 1)
 
                        'ADMIN MENU -- USER MUST HAVE RIGHTS TO DO THIS
                        If UserTypeID = 3 Then
                              SiteNavigationItems(2) = New SiteNavigationItem("Admin", "/admin/defaultAdmin.aspx", 2)
                              'Create Child Navigation Items
                                    SiteNavigationSubItems(6) = New SiteNavigationItem("Admin #1", "admin/admin1.aspx", 6, 2)
                                    SiteNavigationSubItems(7) = New SiteNavigationItem("Admin #2", "reviews/admin2.aspx", 7, 2)
                                    SiteNavigationSubItems(8) = New SiteNavigationItem("Admin #3", "reviews/admin3.aspx", 8, 2)
                        End If
            End Sub
            Public Sub New(ByRef TopNav As PlaceHolder, ByRef LeftNav As PlaceHolder, ByVal UserTypeID As Integer)
                  TopNav_Placeholder = TopNav
                  LeftNav_Placeholder = LeftNav
 
                  ReDim SiteNavigationItems(1)
                  ReDim SiteNavigationSubItems(5)
 
                  'Create Parent Navigation Items
                        'REPORTS
                              SiteNavigationItems(0) = New SiteNavigationItem("Reports", "reports/defaultReports.aspx", 0)
                              'Create Child Navigation Items
                                    SiteNavigationSubItems(0) = New SiteNavigationItem("Report #1", "reports/report1.aspx", 0, 0)
                                    SiteNavigationSubItems(1) = New SiteNavigationItem("Report #2", "reports/report2.aspx", 1, 0)
                                    SiteNavigationSubItems(2) = New SiteNavigationItem("Report #3", "reports/report3.aspx", 2, 0)
 
                        'REVIEWS
                              SiteNavigationItems(1) = New SiteNavigationItem("Reviews", "/reviews/defaultReviews.aspx", 1)
                              'Create Child Navigation Items
                                    SiteNavigationSubItems(3) = New SiteNavigationItem("#1 - Project Setup", "reviews/frmReviews_ProjectSetup.aspx", 3, 1)
                                    SiteNavigationSubItems(4) = New SiteNavigationItem("#2 - Source Setup Entry", "reviews/frmReviews_SourceSetup_Entry.aspx", 3, 1)
                                    SiteNavigationSubItems(5) = New SiteNavigationItem("#3 - Source Setup - List", "reviews/frmReviews_SourceSetup_List.aspx", 3, 1)
 
                        'ADMIN MENU -- USER MUST HAVE RIGHTS TO DO THIS
                        If UserTypeID = 3 Then
                              ReDim Preserve SiteNavigationItems(2)
                              ReDim Preserve SiteNavigationSubItems(8)
 
                              SiteNavigationItems(2) = New SiteNavigationItem("Admin", "/admin/defaultAdmin.aspx", 2)
                              'Create Child Navigation Items
                                    SiteNavigationSubItems(6) = New SiteNavigationItem("Admin #1", "admin/admin1.aspx", 6, 2)
                                    SiteNavigationSubItems(7) = New SiteNavigationItem("Admin #2", "reviews/admin2.aspx", 7, 2)
                                    SiteNavigationSubItems(8) = New SiteNavigationItem("Admin #3", "reviews/admin3.aspx", 8, 2)
                        End If
            End Sub
                  Private Sub TopNavButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
                              Dim b As LinkButton = CType(sender, LinkButton)
                              Dim currIndex As Integer
 
                              'Grab the Index of the button
                                    currIndex = Mid(b.ID, InStr(b.ID, "_") + 1)
 
                              'Fill Left Nav
                                    FillLeftNav(LeftNav_Placeholder, currIndex)
                  End Sub
                  Private Sub LeftNavButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
                              Dim b As LinkButton = CType(sender, LinkButton)
                              Dim currIndex As Integer
 
                              'Grab the Index of the button
                                    currIndex = Mid(b.ID, InStr(b.ID, "_") + 1)
 
                              'Redirect to different page
                                    b.Page.Server.Transfer(SiteNavigationSubItems(currIndex.ToString).HREF, True)
 
                  End Sub
 
   Public Sub FillTopNav(ByRef myholder As PlaceHolder)
                  'GIVEN: Placeholder
                  'RETURNS: nothing
                  'ACTION: Populates placeholder with link buttons
 
                  'Remove existing controls  
                        myholder.Controls.Clear()
 
                  'Add Existing controls
                        'Create table header/start row
                              myholder.Controls.Add(New LiteralControl("<TABLE>" & vbCrLf & "   <TR>"))
 
                        Dim i As Integer, newLink As LinkButton
                        For i = 0 To SiteNavigationItems.GetUpperBound(0)
                              myholder.Controls.Add(New LiteralControl("<TD>"))
 
                              'add hyperlink
                                    newLink = New LinkButton
                                    newLink.ID = "TopNavButtonID_" & i
                                    newLink.CssClass = "linkButton"
                                    newLink.Text = SiteNavigationItems(i).Text
                                    AddHandler newLink.Click, AddressOf TopNavButton_Click
 
                                    myholder.Controls.Add(newLink)
 
                              myholder.Controls.Add(New LiteralControl("<TD>"))
                        Next
 
                        'Create table end row/footer
                              myholder.Controls.Add(New LiteralControl("   </TR>" & vbCrLf & "</TABLE>"))
            End Sub
      Public Sub FillLeftNav(ByRef myholder As PlaceHolder, ByVal SelectedParentIndex As Integer)
            'Grab all the child navigation items of the parent
                  Dim SelectedNavigationitems() As SiteNavigationItem
                  Dim x As Integer
                  Dim currNavItemsFound As Integer = 0
                  For x = 0 To SiteNavigationSubItems.GetUpperBound(0)
                        If (SiteNavigationSubItems(x).ParentIndex = SelectedParentIndex) Then
                              ReDim Preserve SelectedNavigationitems(currNavItemsFound)
                              SelectedNavigationitems(currNavItemsFound) = New SiteNavigationItem(SiteNavigationSubItems(x).Text, SiteNavigationSubItems(x).HREF, SiteNavigationSubItems(x).ParentIndex)
                              currNavItemsFound += 1
                        End If
                  Next
 
            'Remove existing controls  
                  myholder.Controls.Clear()
 
            'Add Existing controls
                  'Create table header/start row
                        myholder.Controls.Add(New LiteralControl("<TABLE>" & vbCrLf))
 
                        Dim i As Integer, newLink As LinkButton
                        For i = 0 To SelectedNavigationitems.GetUpperBound(0)
                              myholder.Controls.Add(New LiteralControl("<TR>" & vbCrLf & "      <TD valign=top><img src=" & ChrW(34) & "Images/nav_bullet_red.gif" & ChrW(34) & "></TD>" & vbCrLf & "<TD valign=top>"))
 
                              'add hyperlink
                                    newLink = New LinkButton
                                    newLink.ID = "LeftNavID_" & SelectedNavigationitems(i).Index
                                    newLink.CssClass = "linkButton"
                                    newLink.Text = SelectedNavigationitems(i).Text
                                    AddHandler newLink.Click, AddressOf LeftNavButton_Click
                                    myholder.Controls.Add(newLink)
 
                              myholder.Controls.Add(New LiteralControl("   </TD>" & vbCrLf & "</TR>"))
                        Next
 
                        'Create table end row/footer
                              myholder.Controls.Add(New LiteralControl("   </TABLE>"))
      End Sub
 

            Public Function GetSiteNavigationItems() As SiteNavigationItem()
                  Return SiteNavigationItems
            End Function
      Public Function GetSiteNavigationSubItems(ByVal ParentIndex As Integer) As SiteNavigationItem()
            'Grab all the child navigation items of the parent
                  Dim SelectedNavigationitems() As SiteNavigationItem
                  Dim x As Integer
                  Dim currNavItemsFound As Integer = 0
                  For x = 0 To SiteNavigationSubItems.GetUpperBound(0)
                        If (SiteNavigationSubItems(x).ParentIndex = ParentIndex) Then
                              ReDim Preserve SelectedNavigationitems(currNavItemsFound)
                              SelectedNavigationitems(currNavItemsFound) = New SiteNavigationItem(SiteNavigationSubItems(x).Text, SiteNavigationSubItems(x).HREF, SiteNavigationSubItems(x).ParentIndex)
                              currNavItemsFound += 1
                        End If
                  Next
 
            'Return all the children of selected menu
                  Return SelectedNavigationitems
      End Function
      Public Function GetTopNav() As SiteNavigationItem()
            Return SiteNavigationItems
      End Function
 
      Public Function DisplayTopNav(Optional ByVal indent As Integer = 0) As String
            'Function displays the navigation that goes with the nav
            Dim currTopNavIX As Integer
            For currTopNavIX = 0 To SiteNavigationItems.GetUpperBound(0)
                  DisplayTopNav = DisplayTopNav.Concat(DisplayTopNav, _
                  "         <TD><asp:HyperLink id=" & ChrW(34) & "link" & currTopNavIX.ToString & ChrW(34) & " runat=" & ChrW(34) & "server" & ChrW(34) & ">" & HttpUtility.HtmlEncode(SiteNavigationItems(currTopNavIX).Text) & "</asp:HyperLink></TD>")
            Next
 
            DisplayTopNav = DisplayTopNav.Concat(vbCrLf & _
                                          "<TABLE>" & vbCrLf & _
                                          "   <TR>" & vbCrLf, _
                                          "         <TD><img border=0 src=" & ChrW(34) & "Images/sm_PennDot.jpg" & ChrW(34) & "></TD>" & vbCrLf & _
                                          "         <TD width=100%></TD>" & vbCrLf & _
                                          DisplayTopNav, _
                                          "   </TR>" & _
                                          "</TABLE>")
 
            DisplayTopNav = DisplayTopNav.Replace(vbCrLf, Space(indent) & vbCrLf)
      End Function
 

      Public Class SiteNavigationItem
            'This class defines individual site navigation objects -- navigation links
            Private _Text As String, _
                  _HREF As String, _
                  _ParentIndex As Integer, _
                  _Index As Integer
#Region "         SiteNavigationItem Constructors"
            Public Sub New(ByVal Text As String, ByVal HREF As String, ByVal Index As Integer)
                  'Create the new Site Navigation Item
                  _Text = Text
                  _HREF = HREF
                  _ParentIndex = 0
                  _Index = Index
            End Sub
            Public Sub New(ByVal Text As String, ByVal HREF As String, ByVal Index As Integer, ByVal ParentIndex As Integer)
                  'Create the new Site Navigation Item
                  _Text = Text
                  _HREF = HREF
                  _ParentIndex = ParentIndex
                  _Index = Index
            End Sub
#End Region
 
#Region "         SiteNavigationItem Properties"
            Public Property Index() As Integer
                  Get
                        Return _Index
                  End Get
                  Set(ByVal Value As Integer)
                        _Index = Value
                  End Set
            End Property
            Public Property ParentIndex() As Integer
                  Get
                        Return _ParentIndex
                  End Get
                  Set(ByVal Value As Integer)
                        _ParentIndex = Value
                  End Set
            End Property
            Public Property Text() As String
                  Get
                        Return _Text
                  End Get
                  Set(ByVal Value As String)
                        _Text = Value
                  End Set
            End Property
            Public Property HREF() As String
                  Get
                        Return _HREF
                  End Get
                  Set(ByVal Value As String)
                        _HREF = Value
                  End Set
            End Property
#End Region
      End Class
End Class
</code>
 

GeneralRe: AdvancedPageInheritance code in VB not working...PLEASE HELP! PinmemberSpiff Dog25-Sep-04 14:34 
GeneralRe: AdvancedPageInheritance code in VB not working...PLEASE HELP! Pinmemberbretonk27-Sep-04 3:25 
GeneralRe: AdvancedPageInheritance code in VB not working...PLEASE HELP! PinmemberSpiff Dog27-Sep-04 13:10 
GeneralValidationControls PinmemberDomenic6-Aug-04 8:19 
GeneralRe: ValidationControls Pinmemberpanurge11-Aug-04 10:18 
GeneralRe: ValidationControls Pinmemberkenneth Keeley18-Aug-04 21:07 
GeneralRe: ValidationControls PinmemberDomenic19-Aug-04 3:32 
GeneralRe: ValidationControls Pinmemberrwm@pobox.com26-Aug-04 21:44 
GeneralRe: ValidationControls PinsussAnonymous23-Sep-04 1:53 
GeneralRe: ValidationControls Pinmemberkernings28-Sep-04 21:44 
GeneralRe: ValidationControls PinmemberGRF25-Sep-04 16:18 
GeneralRe: ValidationControls PinmemberaeLogic26-Sep-04 15:53 
GeneralRe: ValidationControls PinsussAnonymous26-Sep-04 18:07 
GeneralPage Title PinmemberDomenic19-Jul-04 8:21 
GeneralRe: Page Title PinmemberSpiff Dog23-Aug-04 11:56 
GeneralSimple Page Inheritance in VB.net PinsussAnonymous21-Jun-04 5:25 
GeneralDesigner modifies inherited code behind PinsussChagai8-May-04 21:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 20 Sep 2002
Article Copyright 2002 by Peter Provost
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid