Introduction
Throughout my Web designing days, I always needed navigation menus with dynamic content which are also easily editable and customizable. Last month, I decided to write a simple menu control which uses CSS to style and uses XML as source for menu items.
Navigation Menu Server Control
="1.0"="utf-8"
<menuitems>
<item id="1" url="Default.aspx" linkname="Main Page"
description="Main Page of web siter"/>
<item id="2" url="Default2.aspx"
linkname="Company" description="Company Details"/>
<item id="3" url="Default3.aspx"
linkname="Photos" description="Photo Gallery"/>
<item id="4" url="Default4.aspx"
linkname="Contact" description="Contact Form"/>
</menuitems>
This is the XML template for menu items and links.
From the Visual Studio menu, follow the tree: File - New - Project - Web - ASP.NET Server Control, and create a new server control project. By default, ServerControl1.cs is installed. Right click the project and add a new Class called xmlreader.cs In this class, first of all, we define an object that represents menu item. Let's call it menuitem
for simplicity's sake.
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Text;
using System.Collections;
public class menuitem
{
public menuitem() { }
private string id;
private string url;
private string linkname;
private string description;
public string Id { get { return id; } set { id = value; } }
public string Url { get { return url; } set { url = value; } }
public string Linkname { get { return linkname; } set { linkname = value; } }
public string Description { get { return description; }
set { description = value; } }
}
After defining menuitem
, we will create an instance of an arraylist
class called getMenu
into the xmlreader
class. In the getMenu
method, we read XML with XLINQ. This method takes two parameters:
public ArrayList getMenu(string xmlPath, string xmlFileName)
{
ArrayList menuitems = new ArrayList();
try
{
XElement xmenu = XElement.Load(xmlPath + xmlFileName);
if (xmenu != null)
{
var xc = from c in xmenu.Elements("item")
orderby c.Attribute("id").Value
select new
{
ID = c.Attribute("id"),
URL = c.Attribute("url"),
LINKNAME = c.Attribute("linkname"),
DESCRIPTION = c.Attribute("description")
};
foreach (var l in xc)
{
menuitem itm = new menuitem();
itm.Id = l.ID.Value;
itm.Url = l.URL.Value;
itm.Linkname = l.LINKNAME.Value;
itm.Description = l.DESCRIPTION.Value;
menuitems.Add(itm);
}
}
}
catch (Exception ex)
{
throw ex;
}
return menuitems;
}
In the above methods, we created an arraylist
. Now we have to create our HTML code. To do this, we go to the ServerControl1.cs class.
The menuHtmlGenerator
method is the one that takes items in the arraylist
, we build with getMenu
in xmlreader
and creates the markup code for HTML page.
protected string menuHtmlGenerator(ArrayList aList)
{
StringBuilder s = new StringBuilder();
for (int i = 0; i < aList.Count; i++)
{
s.Append(System.Environment.NewLine);
s.Append("<li >");
s.Append("<a href ='" + ((menuitem)aList[i]).Url + "' ");
s.Append("title='" + ((menuitem)aList[i]).Description + "' ");
if (useDiffCssForCrrntItem)
{
if (((menuitem)aList[i]).Id == currentItemId)
s.Append("class='" + currentItemClass + "' ");
}
s.Append(">");
s.Append("<span>" + ((menuitem)aList[i]).Linkname + "</span> ");
s.Append("</a>");
s.Append("</li>");
s.Append(System.Environment.NewLine);
}
return s.ToString();
}
}
After generating HTML code, we use a method derived from WebControl
. In the method, the first thing we do is declare properties of the menu. They will be used as design-time attributes to customize the control.
public class ServerControl1 : WebControl
{
#region 7 properties for design-time attritubes
private string xmlPath;
private string xmlFileName;
private string menuClass;
private string menuId;
private bool useDiffCssForCrrntItem = false;
private string currentItemClass;
private string currentItemId;
#endregion
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
#region 4 Member properties Used as Design-Time Attributes for
Our Server Control
public string XmlPath { get { return xmlPath; } set { xmlPath = value; } }
public string XmlFileName { get { return xmlFileName; }
set { xmlFileName = value; } }
public string MenuClass { get { return menuClass; }
set { menuClass = value; } }
public string MenuId { get { return menuId; }
set { menuId = value; } }
public bool UseDiffCssForCrrntItem { get { return useDiffCssForCrrntItem; }
set { useDiffCssForCrrntItem = value; } }
public string CurrentItemClass { get { return currentItemClass; }
set { currentItemClass = value; } }
public string CurrentItemId { get { return currentItemId; }
set { currentItemId = value; } }
#endregion
protected override void RenderContents(HtmlTextWriter output)
{
try
{
xmlreader myData = new xmlreader();
output.Write("<div class='" + menuClass +
"' id='" + menuId + "'>");
output.Write("<ul>");
output.Write(menuHtmlGenerator(myData.getMenu(xmlPath, xmlFileName)));
output.Write("</ul>");
output.Write("</d i v></div>");
}
catch (Exception ex)
{
output.Write(ex);
}
}
After we build our project in Visual Studio, right click the head of the toolbox and click Choose Items and select DLL file from the bin folder.
After that, drag and drop the new item to the page. Set the properties. Prepare the XML file which is in the sample project.
Points of Interest
This menu control is a sample of what you can do with server controls. They are powerful and fast.
History
- 8th August, 2008: Initial version