Using Custom Controls and the Site Navigation API

This tutorial shows how to add a custom web control to an ASP.NET site and create a site-wide menu using the site navigation API.

Create the application

Start Webbo and create a new folder named 'Control Demo' to contain the project. Make it the root of the Explorer view to allow the preview server to run with the project as its document root. Create the site using the 'New From Template' menu to add a new 'Website with Master Page' project from the 'ASP.NET/Projects' submenu.

To demonstrate the site navigation API we need to create some test pages for the site menu. Use the Explorer view 'Clone' option to create three copies of the default content page 'Default.aspx'.

Next we need a sitemap file to define the site layout. From the 'New From Template' menu create a new 'Web Sitemap' from the 'ASP.NET/Configuration' submenu, this will add 'Web.sitemap' to the project. As there are files already present in the project Webbo will present a warning to prevent the accidental overwriting of an existing sitemap. Click 'Yes' to allow the new file to be added.

Finally we need a custom control to generate the site menu from the sitemap file. The following code provides a simple list-based menu control based on the root level of the sitemap file:

using System;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace QuickSharp.Web.Controls
{
    public class SiteRootList : Control
    {
        public override void RenderControl(HtmlTextWriter output)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<ul>");
            CreateListItem(sb, SiteMap.RootNode);
            foreach (SiteMapNode childNode in SiteMap.RootNode.ChildNodes)
                CreateListItem(sb, childNode);
            sb.Append("</ul>");
            output.Write(sb.ToString());
        }

        private void CreateListItem(StringBuilder sb, SiteMapNode node)
        {
            sb.Append("<li><a href=\"");
            sb.Append(node.Url);
            sb.Append("\">");
            sb.Append(node.Title);
            sb.Append("</a></li>");
        }
    }
}

Download the control here, add a folder named 'bin' to the project root and copy the control into it. The project should now look like this:

Project Contents

Create the navigation

Open 'Web.sitemap' in the editor and add a node for each of the pages in the project so that it looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="~/Default.aspx" title="Home" description="Home Page">
        <siteMapNode url="~/Default_1.aspx" title="Test Page 1" description="Test Page 1" />
        <siteMapNode url="~/Default_2.aspx" title="Test Page 2" description="Test Page 2" />
        <siteMapNode url="~/Default_3.aspx" title="Test Page 3" description="Test Page 3" />
    </siteMapNode>
</siteMap>

Now start the ASP.NET Web Server and preview the page 'Default.aspx' to test what we have so far, all being well we should see a blank home page.

Add the server control

Open 'Site.master' in the editor and create a new line after the master page directive on line 1. Type '<' and press ctrl+space. Select '<@' and press enter, then press ctrl+space again to select the 'Register' directive. Next press ctrl+space to select 'Namespace' and enter 'QuickSharp.Web.Controls' for the attribute value. Finally use ctrl+space to select 'Assembly' and use 'SiteRootListControl' for the value.

<%@ Register Tagprefix="cc" Namespace="QuickSharp.Web.Controls" Assembly="SiteRootListControl" %>

With this directive we have made the server control available to the page using the custom control tag 'cc'. Technically, we don't need the namespace attribute for the control to appear in the page but without it Webbo will be unable to provide Code Assist support for the control.

Finally, add the control to the page. Open a new line after the opening tag of the 'form' element and type '<cc:'. Press ctrl+space to show the controls available with the 'cc' tag prefix, the list control should appear as the sole choice.

Custom Control Code Assist

Select the control to insert it into the page with an ID of your choice. Preview the site again and this time the menu should be visible.

The master page should look like this:

<%@ Master Language="C#" AutoEventWireup="true" %>
<%@ Register Tagprefix="cc" Namespace="QuickSharp.Web.Controls" Assembly="SiteRootListControl" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head runat="server">
    <title></title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <link type="text/css" rel="stylesheet" href="Site.css" />
</head>
<body>
    <form id="form1" runat="server">
        <cc:SiteRootList ID="menu" runat="server"></cc:SiteRootList>
        <asp:ContentPlaceHolder ID="MainContentPlaceHolder" runat="server">
        </asp:contentplaceholder>
    </form>
</body>
</html>