Recipe 5.3. Creating a Customizable Navigation Bar


Problem

You want to create a navigation bar that lets you add or remove items without changing code so you can reuse the navigation bar in multiple applications.

Solution

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:

  1. Create a file with a .ascx extension.

  2. Place the @ Control directive at the top of the file.

  3. Add a DataList control configured to render a table with an ItemTemplate defining the cells in the table.

In the code-behind class for the control, use the .NET language of your choice to:

  1. Create a user control code-behind class that inherits from the UserControl class.

  2. (Optional) Establish properties for the control that will provide the ability to control programmatically the basic look of the navigation bar, such as its background color.

To use the user control in an ASP.NET page:

  1. Register the control by using the @ Register directive at the top of the page.

  2. 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 5-2. Example 5-7 shows the XML document we created to define the contents of the navigation bar. Example 5-8 shows the .ascx file for the user control. Examples 5-9 and 5-10 show the VB and C# code-behind files for the user control. Example 5-11 shows the .aspx file for the test page that uses the user control. Examples 5-12 and 5-13 show the VB and C# code-behind files for the test page.

Figure 5-2. Customizable navigation bar output


Discussion

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. Using a DataSet and DataList control in this way has three advantages:

  1. You are not limited to the number of items in the navigation bar.

  2. Loading the XML document used to define the navigation bar items into a DataSet makes for easy traversal of those items.

  3. A DataList control configured to render a table with an ItemTemplate 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 5-7. This is 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 5-8, 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 Examples 5-9 (VB) and 5-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 used to populate the navigation bar. The navBarName property is used to define the name of the group of elements in the XML document 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:

  1. In the Page_Load method of the code-behind, the XML document containing the navigation bar data is read into a DataSet and then bound to the DataList.

  2. The dlNavBar_ItemDataBound method is then called by ASP.NET for each of the items defined in the XML document (rows in the DataSet). Its job is to set the HRef of the anchor tag and then set the image source and alt 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 5-11 shows how this is done in our application, including the use of TagPrefix, TagName, and Src attributes 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 5.1 for more details on these attributes).

In our example, the three properties of the navigation bar control must be set. Setting these in the .aspx file is possible; 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 Examples 5-12 (VB) and 5-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.

The performance of the navigation control shown in this recipe can be improved by caching the control, as described in Recipe 16.6.


See Also

Recipe 16.6 for caching user controls

Example 5-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=2</ButtonLink> <ImageSrc>images/nav/button_nav_datagrids_off.gif</ImageSrc> <AltText>Datagrids</AltText>   </Public>   <Public>     <ButtonLink>../ProblemMenu.aspx?Chapter=3</ButtonLink> <ImageSrc>images/nav/button_nav_validation_off.gif</ImageSrc> <AltText>Validation</AltText>   </Public>   <Public>     <ButtonLink>../ProblemMenu.aspx?Chapter=4</ButtonLink> <ImageSrc>images/nav/button_nav_forms_off.gif</ImageSrc> <AltText>Forms</AltText>   </Public>   <Public>     <ButtonLink>../ProblemMenu.aspx?Chapter=5</ButtonLink> <ImageSrc>images/nav/button_nav_user_controls_off.gif</ImageSrc> <AltText>User Controls</AltText>   </Public> </NavBar> 

Example 5-8. Customizable navigation bar (.ascx)

 <%@ Control Language="VB" AutoEventWireup="false"   CodeFile="CH05UserControlNavBarVB.ascx.vb"   Inherits="ASPNetCookbook.VBExamples.CH05UserControlNavBarVB" %> <asp:datalist  runat="server"   width="100%" borderwidth="0"   cellpadding="0" cellspacing="0" height="29"   repeatdirection="Horizontal" repeatlayout="Table"   OnItemDataBound="dlNavBar_ItemDataBound">   <itemtemplate>     <td height="25" align="center">   <a  runat="server" >   <img  runat="server" border="0"     alt="" src="/books/1/505/1/html/2/"/></a> </td>   </itemtemplate> </asp:datalist> 

Example 5-9. Customizable navigation bar (.vb)

 Option Explicit On Option Strict On Imports System.Data Imports System.Web.UI.WebControls Namespace ASPNetCookbook.VBExamples   ''' <summary>   ''' This class provides the code behind for   ''' CH05UserControlNavBarVB.ascx   ''' </summary>   Partial Class CH05UserControlNavBarVB     Inherits System.Web.UI.UserControl '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" '''*********************************************************************** ''' <summary> ''' This property provides the ability get/set the background color used ''' for the navigation bar ''' </summary> 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 '''*********************************************************************** ''' <summary> ''' This property provides the ability get/set the name of the xml file ''' used to define the navigation bar ''' </summary> Public Property xmlFilename() As String   Get     Return (mXMLFilename)   End Get   Set(ByVal value As String)     mXMLFilename = value   End Set     End Property '''*********************************************************************** ''' <summay> ''' This property provides the ability get/set the name of the navigation ''' bar definition in the xml file ''' </summary> Public Property navBarName() As String     Get   Return (mNavBarName) End Get Set(ByVal value As String)   mNavBarName = value End Set End Property '''*********************************************************************** ''' <summary> ''' This routine provides the event handler for the page load event. It ''' is responsible for initializing the controls on the page. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Protected Sub Page_Load(ByVal sender As Object, _   ByVal e As System.EventArgs) Handles Me.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 '''*********************************************************************** ''' <summary> ''' 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. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Protected Sub dlNavBar_ItemDataBound(ByVal sender As Object, _    ByVal e As DataListItemEventArgs) '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 'dlNavBar_ItemDataBound   End Class 'CH05UserControlNavBarVB End Namespace 

Example 5-10. Customizable navigation bar (.cs)

 using System; using System.Data; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls;    namespace ASPNetCookbook.CSExamples   {     /// <summary> /// This class provides the code behind for /// CH05UserControlNavBarCS.ascx /// </summary> public partial class CH05UserControlNavBarCS : System.Web.UI.UserControl {   // 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";   ///***********************************************************************   /// <summary>   /// This property provides the ability get/set the background color used   /// for the navigation bar   /// </summary>   public System.Drawing.Color backgroundColor   { get {   return dlNavBar.BackColor; } set {   dlNavBar.BackColor = value; }   } // backgroundColor   ///***********************************************************************   /// <summary>   /// This property provides the ability get/set the name of the xml file   /// used to define the navigation bar   /// </summary>   public String xmlFilename   { get {   return mXMLFilename; } set {   mXMLFilename = value; }    } // xmlFilename    ///***********************************************************************    /// <summary>    /// This property provides the ability get/set the name of the navigation    /// bar definition in the xml file    /// </summary>    public String navBarName    {   get   {     return mNavBarName;   }   set   {     mNavBarName = value; }   } // navBarName  ///***********************************************************************  /// <summary>  /// This routine provides the event handler for the page load event.  /// It is responsible for initializing the controls on the page.  /// </summary>  ///  /// <param name="sender">Set to the sender of the event</param>  /// <param name="e">Set to the event arguments</param>  protected void Page_Load(object sender, EventArgs e)  {     DataSet dsNavBarData; // 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();   } // Page_Load   ///***********************************************************************   /// <summary>   /// 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.   /// </summary>   ///   /// <param name="sender">Set to the sender of the event</param>   /// <param name="e">Set to the event arguments</param>   protected void dlNavBar_ItemDataBound(Object sender,   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; HtmlImage imageControl; DataRowView dRow; // 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]);      }   } // dlNavBar_ItemDataBound    } // CH05UserControlNavBarCS } 

Example 5-11. Using the navigation bar (.aspx)

 <%@ Page Language="VB" MasterPageFile="~/ASPNetCookbookVB.master"   AutoEventWireup="false"   CodeFile="CH05DisplayNavBarVB.aspx.vb"   Inherits="ASPNetCookbook.VBExamples.CH05DisplayNavBarVB"   Title="User Control Display Navigation Bar" %> <%@ Register TagPrefix="ASPCookbook" TagName="NavBar"  src="/books/1/505/1/html/2/CH05UserControlNavBarVB.ascx" %> <asp:Content  Runat="server" ContentPlaceHolder>      <table width="100%" align="center" border="0"    cellpadding="0" cellspacing="0" >         <tr>    <td>         <ASPCookbook:NavBar  runat="server" />    </td>   </tr>  </table> </asp:Content> 

Example 5-12. Using the navigation bar (.vb)

 Option Explicit On Option Strict On Imports System.Drawing Namespace ASPNetCookbook.VBExamples   ''' <summary>   ''' This class provides the code behind for   ''' CH05DisplayNavBarVB.aspx   ''' </summary>   Partial Class CH05DisplayNavBarVB     Inherits System.Web.UI.Page '''*********************************************************************** ''' <summary> ''' This routine provides the event handler for the page load event. It ''' is responsible for initializing the controls on the page. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load 'initialize the navbar user control navBar.xmlFilename = Server.MapPath("xml") & "\NavigationBar.xml" navBar.navBarName = "Public" navBar.backgroundColor = ColorTranslator.FromHtml("#6B0808") End Sub 'Page_Load   End Class 'CH05DisplayNavBarVB  End Namespace 

Example 5-13. Using the navigation bar (.cs)

 using System; using System.Drawing; namespace ASPNetCookbook.CSExamples { /// <summary> /// This class provides the code behind for /// CH05DisplayNavBarCS.aspx /// </summary> public partial class CH05DisplayNavBarCS : System.Web.UI.Page {   ///***********************************************************************   /// <summary>   /// This routine provides the event handler for the page load event.   /// It is responsible for initializing the controls on the page.   /// </summary>   ///   /// <param name="sender">Set to the sender of the event</param>   /// <param name="e">Set to the event arguments</param>   protected void Page_Load(object sender, EventArgs e)   {     // initialize the navbar user control navBar.xmlFilename = Server.MapPath("xml") + "\\NavigationBar.xml"; navBar.navBarName = "Public"; navBar.backgroundColor = ColorTranslator.FromHtml("#6B0808");   }  // Page_Load    } // CH05DisplayNavBarCS } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2003
Pages: 202

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net