You want to create a navigation bar that lets you add or remove items without changing code so that you can reuse the navigation bar in multiple applications.
Create an XML document containing the items that will be displayed in the navigation bar, and then create a user control that uses the contents of the XML document to provide the required customization.
To create the user control:
In the code-behind class for the control, use the .NET language of your choice to:
Create a user control code-behind class that inherits from the
UserControl
class.(Optional) Establish properties for the control that will provide the ability to programmatically control the basic look of the navigation bar, such as its background color.
To use the user control in an ASP.NET page:
Register the control by using the
@ Register
directive at the top of the page.Place the tag for the user control in the HTML where you want the control rendered.
The output of a test page demonstrating a typical navigation bar user
control is shown in Figure 4-2. Example 4-7 shows the XML document we created to define
the contents of the navigation bar. Example 4-8
shows the .ascx
file for the user control.
Example 4-9 and Example 4-10 show the VB and C# code-behind files for the
user control. Example 4-11 shows the
.aspx
file for the test page that uses the user
control. Example 4-12 and Example 4-13 show the VB and C# code-behind files for the
test page.
The general strategy for this solution is to create an XML document
that defines the contents of the navigation bar user control. You
then use the Page_Load
method of the user
control’s code-behind to read into a
DataSet
the XML document containing the navigation
bar data and then bind the dataset to a DataList
control. The use of a DataSet
and
DataList
control may sound a little unconventional
in this application, but it has these distinct advantages:
You are not limited to the number of items in the navigation bar.
Loading the XML document used to define the navigation bar items into a
DataSet
makes for easy traversal of those items.A
DataList
control configured to render a table with anItemTemplate
provides the flexibility in the display of the columns that is needed for customizing a navigation bar.
The example we have written to implement this solution creates a navigation bar user control whose contents are defined by an XML document. But the example goes a bit further in that it provides the ability to define what buttons appear in the navigation bar as well as the ability to customize the color of the bar, change the name of the XML file used to define the bar, and set other properties.
The XML document that defines our navigation bar consists of a series
of elements named Public
, as shown in Example 4-7. This is actually the name of the navigation
bar (explained later). Each of the Public
elements
contains three elements: the ButtonLink
element
defines the URL for the navigation bar button, the
ImageSrc
element defines the image used for the
button, and the AltText
element sets the text
alternative for the image (i.e., the value of the
Alt
attribute of the IMG
tag
used for the button).
The .ascx
file for our example user control,
which is shown in Example 4-8, simply contains a
DataList
control configured to render a table with
an ItemTemplate
to define the cells in the table.
The ItemTemplate
contains an anchor tag used for
the navigation and an image tag to display the graphic button.
The code-behind for our example user control, shown in Example 4-9 (VB) and Example 4-10 (C#),
contains three properties to enable customization of the navigation
bar. The backgroundColor
property provides the
ability to change the background color of the navigation bar. The
xmlFilename
property defines the XML document that
is used to populate the navigation bar. The
navBarName
property is used to define the name of
the group of elements in the XML document that are used to populate
the navigation bar. In this example, all of the elements are named
Public
. The example’s design
allows the XML document to have any number of other element groups,
thus providing the ability to have a different navigation bar on
different pages depending on the page type, user role, context, or
the like. If you wanted a different navigation bar for the private
pages in the site, for example, you would add a group of
Private
elements with the information needed to
define the private navigation bar. How to select one is described
later.
Our approach advocates leveraging a DataList
tabular control for the workings of the navigation bar.
Here’s how we populate the
DataList
:
In the
Page_Load
method of the code-behind, the XML document containing the navigation bar data is read into aDataSet
and then bound to theDataList
.The
dlNavBar_ItemDataBound
method is then called by ASP.NET for each of the items defined in the XML document (rows in theDataSet
). Its job is to set theHRef
of the anchor tag and then set the image source andalt
text for the image tag.
To use the navigation bar user control in an
.aspx
page, the control must be registered with
the @ Register
directive at the top of the page
and then the navigation bar control can be inserted into your page.
Example 4-11 shows how this is done in our
application, including the use of TagPrefix
,
TagName
, and Src
attributes
that are set to the namespace of the project, the name of the
control, and the name (and virtual path) of the
.ascx
file of the user control, respectively
(see Recipe 4.1 for more details on
these attributes).
In our example, the three properties of the navigation bar control
must also be set. It is possible to set these in the
.aspx
file; however, because the
xmlFilename
property must be set to a fully
qualified XML filename, this is better done in the code-behind, as
shown in Example 4-12 (VB) and Example 4-13 (C#).
The navigation bar user control presented here is somewhat bland
compared to most others. For instance, many navigation bars we have
implemented support a changing image to indicate the active location
in the site, complete with mouse-overs for each new image. When
implementing this capability yourself, consider adding additional
image information in the XML document to support the
“on,”
“off,” and
“over” images. The typical
mouse-over code will need to be added to the
.ascx
file, and the code-behind will need a
currentPage
property to provide the ability for it
to change the images displayed as a function of the currently
displayed page.
Tip
The performance of the navigation control shown in this recipe can be significantly improved by caching the control, as described in Recipe 13.5.
Recipe 13.5 for caching user controls
Example 4-7. XML used for customizable navigation bar
<?xml version="1.0" encoding="utf-8"?> <NavBar> <Public> <ButtonLink>../ChapterMenu.aspx</ButtonLink> <ImageSrc>images/nav/button_nav_home_off.gif</ImageSrc> <AltText>Home</AltText> </Public> <Public> <ButtonLink>../ProblemMenu.aspx?Chapter=1</ButtonLink> <ImageSrc>images/nav/button_nav_datagrids_off.gif</ImageSrc> <AltText>Datagrids</AltText> </Public> <Public> <ButtonLink>../ProblemMenu.aspx?Chapter=2</ButtonLink> <ImageSrc>images/nav/button_nav_validation_off.gif</ImageSrc> <AltText>Validation</AltText> </Public> <Public> <ButtonLink>../ProblemMenu.aspx?Chapter=3</ButtonLink> <ImageSrc>images/nav/button_nav_forms_off.gif</ImageSrc> <AltText>Forms</AltText> </Public> <Public> <ButtonLink>../ProblemMenu.aspx?Chapter=4</ButtonLink> <ImageSrc>images/nav/button_nav_user_controls_off.gif</ImageSrc> <AltText>User Controls</AltText> </Public> </NavBar>
Example 4-8. Customizable navigation bar (.ascx)
<%@ Control Language="vb" AutoEventWireup="false" Codebehind="CH04UserControlNavBarVB1.ascx.vb" Inherits="ASPNetCookbook.VBExamples.CH04UserControlNavBarVB1" %><asp:datalist id="dlNavBar" runat="server"
borderwidth="0" cellpadding="0" cellspacing="0" height="29"
repeatdirection="Horizontal" repeatlayout="Table"
width="100%">
<itemtemplate>
<td height="25" align="center">
<a id="anNavBarLink" runat="server" >
<img id="imgNavBarImage" runat="server" border="0"/></a></td>
</itemtemplate>
</asp:datalist>
Example 4-9. Customizable navigation bar code-behind (.vb)
Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH04UserControlNavBarVB1.ascx.vb ' ' Description: This module provides the code behind for ' CH04UserControlNavBarVB1.ascx ' '***************************************************************************** Imports System Imports System.Data Imports System.Web.UI.HtmlControls Imports System.Web.UI.WebControls Namespace ASPNetCookbook.VBExamples Public MustInherit Class CH04UserControlNavBarVB1 Inherits System.Web.UI.UserControl 'controls on the user control Protected WithEvents dlNavBar As System.Web.UI.WebControls.DataList 'private attributes Private mXMLFilename As String Private mNavBarName As String 'The following constants define the elements available 'in the navigation bar XML document Private Const MENU_ITEM_BUTTON_LINK As String = "ButtonLink" Private Const MENU_ITEM_IMAGE_SRC As String = "ImageSrc" Private Const MENU_ITEM_ALT_TEXT As String = "AltText" '************************************************************************* ' ' ROUTINE: backgroundColor ' ' DESCRIPTION: This property provides the ability get/set the ' background color used for the navigation bar '-------------------------------------------------------------------------Public Property backgroundColor( ) As System.Drawing.Color
Get
Return (dlNavBar.BackColor)
End Get
Set(ByVal Value As System.Drawing.Color)
dlNavBar.BackColor = Value
End Set
End Property 'backgroundColor
'************************************************************************* ' ' ROUTINE: xmlFilename ' ' DESCRIPTION: This property provides the ability get/set the ' name of the xml file used to define the navigation bar '-------------------------------------------------------------------------Public Property xmlFilename( ) As String
Get
Return (mXMLFilename)
End Get
Set(ByVal Value As String)
mXMLFilename = Value
End Set
End Property 'xmlFilename
'************************************************************************* ' ' ROUTINE: navBarName ' ' DESCRIPTION: This property provides the ability get/set the ' name of the navigation bar definition in the xml file '-------------------------------------------------------------------------Public Property navBarName( ) As String
Get
Return (mNavBarName)
End Get
Set(ByVal Value As String)
mNavBarName = Value
End Set
End Property 'navBarName
'************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load Dim dsNavBarData As DataSet'load the XML document used to define the navigation bar items
'into a dataset to provide easy traversal
dsNavBarData = New DataSet
dsNavBarData.ReadXml(xmlFilename)
'bind the nav bar data to the repeater on the control
dlNavBar.DataSource = dsNavBarData.Tables(navBarName)
dlNavBar.DataBind( )
End Sub 'Page_Load '************************************************************************* ' ' ROUTINE: dlNavBar_ItemDataBound ' ' DESCRIPTION: This routine provides the event handler for the item ' data bound event of the datalist control in the nav bar. ' It is responsible for setting the anchor and image ' attributes for the item being bound. '-------------------------------------------------------------------------Private Sub dlNavBar_ItemDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) _
Handles dlNavBar.ItemDataBound
'the following constants define the names of the controls in the datalist
Const ANCHOR_CONTROL As String = "anNavBarLink"
Const IMAGE_CONTROL As String = "imgNavBarImage"
Dim anchorControl As HtmlAnchor
Dim imageControl As HtmlImage
Dim dRow As DataRowView
'make sure this is an item or alternating item in the repeater
If ((e.Item.ItemType = ListItemType.Item) Or _
(e.Item.ItemType = ListItemType.AlternatingItem)) Then
'get the data being bound
dRow = CType(e.Item.DataItem, _
DataRowView)
'find the link control then set it to the url
anchorControl = CType(e.Item.FindControl(ANCHOR_CONTROL), _
HtmlAnchor)
anchorControl.HRef = CStr(dRow.Item(MENU_ITEM_BUTTON_LINK))
'find the image control then set the image source and alt text
imageControl = CType(e.Item.FindControl(IMAGE_CONTROL), _
HtmlImage)
imageControl.Src = CStr(dRow.Item(MENU_ITEM_IMAGE_SRC))
imageControl.Alt = CStr(dRow.Item(MENU_ITEM_ALT_TEXT))
End If
End Sub 'repNavBarCell_ItemDataBound
End Class 'CH04UserControlNavBarVB1 End Namespace
Example 4-10. Customizable navigation bar code-behind (.cs)
//---------------------------------------------------------------------------- // // Module Name: CH04UserControlNavBarCS1.ascx.cs // // Description: This module provides the code behind for // CH04UserControlNavBarCS1.ascx // //**************************************************************************** namespace ASPNetCookbook.CSExamples { using System; using System.Data; using System.Drawing; using System.Web; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; public class CH04UserControlNavBarCS1 : System.Web.UI.UserControl { // controls on the user control protected System.Web.UI.WebControls.DataList dlNavBar; // private attributes private String mXMLFilename; private String mNavBarName; // The following constants define the elements available // in the navigation bar XML document private const String MENU_ITEM_BUTTON_LINK = "ButtonLink"; private const String MENU_ITEM_IMAGE_SRC = "ImageSrc"; private const String MENU_ITEM_ALT_TEXT = "AltText"; //************************************************************************ // // ROUTINE: backgroundColor // // DESCRIPTION: This property provides the ability get/set the // background color used for the navigation bar //------------------------------------------------------------------------public System.Drawing.Color backgroundColor
{
get
{
return(dlNavBar.BackColor);
}
set
{
dlNavBar.BackColor = value;
}
} // backgroundColor
//************************************************************************ // // ROUTINE: xmlFilename // // DESCRIPTION: This property provides the ability get/set the // name of the xml file used to define the navigation bar //------------------------------------------------------------------------public String xmlFilename
{
get
{
return(mXMLFilename);
}
set
{
mXMLFilename = value;
}
} // xmlFilename
//************************************************************************ // // ROUTINE: navBarName // // DESCRIPTION: This property provides the ability get/set the // name of the navigation bar defintion in the xml file //------------------------------------------------------------------------public String navBarName
{
get
{
return(mNavBarName);
}
set
{
mNavBarName = value;
}
} // navBarName
//************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the user control. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { // wire the item data bound event this.dlNavBar.ItemDataBound += new DataListItemEventHandler(this.dlNavBar_ItemDataBound);// load the XML document used to define the navigation bar items
// into a dataset to provide easy traversal
DataSet dsNavBarData = new DataSet( );
dsNavBarData.ReadXml(xmlFilename);
// bind the nav bar data to the repeater on the control
dlNavBar.DataSource = dsNavBarData.Tables[navBarName];
dlNavBar.DataBind( );
} // Page_Load //************************************************************************ // // ROUTINE: dlNavBar_ItemDataBound // // DESCRIPTION: This routine provides the event handler for the item // data bound event of the datalist control in the nav bar. // It is responsible for setting the anchor and image // attributes for the item being bound. //------------------------------------------------------------------------private void dlNavBar_ItemDataBound(Object sender,
System.Web.UI.WebControls.DataListItemEventArgs e)
{
// the following constants define the names of the controls in
// the datalist
const String ANCHOR_CONTROL = "anNavBarLink";
const String IMAGE_CONTROL = "imgNavBarImage";
HtmlAnchor anchorControl = null;
HtmlImage imageControl = null;
DataRowView dRow = null;
// make sure this is an item or alternating item in the repeater
if ((e.Item.ItemType == ListItemType.Item) ||
(e.Item.ItemType == ListItemType.AlternatingItem))
{
// get the data being bound
dRow = (DataRowView)(e.Item.DataItem);
// find the link control then set it to the url
anchorControl = (HtmlAnchor)(e.Item.FindControl(ANCHOR_CONTROL));
anchorControl.HRef = (String)(dRow[MENU_ITEM_BUTTON_LINK]);
// find the image control then set the image source and alt text
imageControl = (HtmlImage)(e.Item.FindControl(IMAGE_CONTROL));
imageControl.Src = (String)(dRow[MENU_ITEM_IMAGE_SRC]);
imageControl.Alt = (String)(dRow[MENU_ITEM_ALT_TEXT]);
}
} // repNavBarCell_ItemDataBound
} // CH04UserControlNavBarCS1 }
Example 4-11. Using the navigation bar (.aspx)
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH04DisplayNavBarVB1.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH04DisplayNavBarVB1" %><%@ Register TagPrefix="ASPCookbook" TagName="NavBar"
Src="CH04UserControlNavBarVB1.ascx" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>User Control Display Navigation Bar</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body> <form id="frmNavBarTest" method="post" runat="server"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="100%" align="center" border="0" cellpadding="0" cellspacing="0" > <tr> <td><ASPCookbook:NavBar id="navBar" runat="server" /> </td> </tr> </table> </form> </body> </html>
Example 4-12. Using the navigation bar code-behind (.vb)
Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH04DisplayNavBarVB1.aspx.vb ' ' Description: This module provides the code behind for ' CH04DisplayNavBarVB1.aspx ' '***************************************************************************** Imports System.Drawing Namespace ASPNetCookbook.VBExamples Public Class CH04DisplayNavBarVB1 Inherits System.Web.UI.Page 'controls on pageProtected navBar As ASPNetCookbook.VBExamples.CH04UserControlNavBarVB1
'************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.LoadnavBar.xmlFilename = Server.MapPath("xml") & "\NavigationBar.xml"
navBar.navBarName = "Public"
navBar.backgroundColor = ColorTranslator.FromHtml("#6B0808")
End Sub 'Page_Load End Class 'CH04DisplayNavBarVB1 End Namespace
Example 4-13. Using the navigation bar code-behind (.cs)
//---------------------------------------------------------------------------- // // Module Name: CH04DisplayNavBarCS1.ascx.cs // // Description: This module provides the code behind for // CH04DisplayNavBarCS1.ascx // //**************************************************************************** using System; using System.Drawing; namespace ASPNetCookbook.CSExamples { public class CH04DisplayNavBarCS1 : System.Web.UI.Page { // controls on formprotected ASPNetCookbook.CSExamples.CH04UserControlNavBarCS1 navBar;
//************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. // //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) {navBar.xmlFilename = Server.MapPath("xml") + "\\NavigationBar.xml";
navBar.navBarName = "Public";
navBar.backgroundColor = ColorTranslator.FromHtml("#6B0808");
} // Page_Load } // CH04DisplayNavBarCS1 }
Get ASP.NET Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.