RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Build an AJAX Content Management System with Visual WebGUI: Adding Menu Components  : Page 2

Menus are basic components of any application. A well-designed menuing framework should be flexible, customizable for both look-and-feel and functionality, and easy to integrate into applications.


Menu Configuration File

You specify menu definitions in an XML file that may be either embedded into assembly as a resource or located in a subfolder of the application.

Here's a sample menu definition file:

<MainMenu DefaultAccesMode="Allow" SecurityHandlerClass="" >
  <MenuItem Name="Main Dashboard" 
    Type= "SampleModules.TestTreeHostModule, MiniCMS">
    <MenuItem Name="Graphic Dashboard" 
      Type= "SampleModules.GraphicDashboard, MiniCMS" Tag=""/>
    <MenuItem Name="Large Graphic Dashboard" 
      Type= "SampleModules.SampleLargeGraphicDashboard, MiniCMS"/>    
  <MenuItem Name="Placeholder" 
    CustomMenuCreator="DocumentsMenu, MiniCMS.DocMenuCreator" 
  <MenuItem Name="Favorites" 
    CustomMenuCreator="FavoritesMenu, MiniCMS.DocMenuCreator" 

Note that the menu definition file has a root element named MainMenu, and that the menu items are sub-elements of type MenuItem. Most MenuItem attributes map to properties of IWTmenuEntryDefinition. Table 2 lists all the possible MenuItem element attributes:

Table 2. MenuItem Element Attributes: The table shows all the possible MenuItem attributes.
Attribute Description
Name The name of the menu, displayed in the menu system. This is the only mandatory attribute.
ID Sets an ID for the menu. If omitted, the system generates a random ID (a new GUID) when the menu item is instantiated.
Icon The icon used for this menu entry. The system first searches for icons embedded as resources in the assembly of the class to be started by module, then in the Icons or Images resource folders as configured in the Visual WebGUI project.
Type Specify the class that defines the module to be launched by menu selection. The class must implement either the IWTModule interface (see this earlier article), or the IWTRunModule interface.
Roles Specifies a comma-delimited list of roles or groups with sufficient rights to view/use this menu item, such as ASP.NET membership roles, or any other custom security/authentication mechanism.
RunModePossible values: Web Desktop Specifies whether a menu item is available in Web mode or Desktop mode. Visual WebGui application offers dual mode (Web and Desktop) functionality from a single code base. Currently, Desktop mode is in early development phases, but this setting aims to offer the possibility of having specific modules available only in a specific run mode. For example, you might implement a module to launch external desktop applications installed on local computer in Desktop mode.
IsPlaceholder Specifies that this MenuItem acts as placeholder. Such MenuItems must include the CustomMenuCreator attribute, which specifies a class that will create menu definition entries dynamically at runtime to replace the MenuItem specified with IsPlaceholder.
CustomMenuCreator This class must implement the interface IWTCustomMenuCreator. It creates a menu definition structure dynamically, which will either replace a menu item specified as IsPlaceholder, or if it does not include IsPlaceholder, will be attached as one or more child menus.

Table 3 shows the attributes of the MainMenu element:

Table 3. MainMenu Element Attributes: The MainMenu element may define these attributes.
Attribute Description
DefaultAccessMode Specifies the access mode for menu items, if no other security rules apply. Possible values are: Allow, and Deny. If missing, the system defaults to Allow.
SecurityHandlerClass This attribute's value is the name of a class that implements the ISecurityHander interface. If present, this component is used to determine the access rights for each menu entry when that menu entry definition is created.

The helper class WTMenuRootDefinitionXml handles the MainMenu element, extracting the values for the DefaultAccessMode and SecurityHandlerClass attributes.

MenuItem elements are handled by WTMenuEntryDefinitionXml, which extends WTMenuEntryDefinitionBase. WTMenuEntryDefinitionXml defines a constructor that accepts an XmlElement parameter containing a MenuItem definition. That sets the internal XmlElement field, loads roles and properties in the corresponding collection, and initializes the ModuleClassName property, as shown below:

public WTMenuEntryDefinitionXml(XmlElement nodeSetting){
   m_nodeSetting = nodeSetting;                      
   ModuleClassName = m_nodeSetting.GetAttribute("Type");

The methods InitRoles and InitProperties parse the corresponding attributes and load the appropriate collections. InitProperties creates a property for every attribute.

private void InitRoles() {
   string roles = m_nodeSetting.GetAttribute(“Roles");
   if (!string.IsNullOrEmpty(roles)){
      // extract all roles in an array
      string[] rolesAry = roles.Split(',');
      for (int i = 0; i < rolesAry.Length; i++)
         // trim spaces and add to Roles collection
         rolesAry[i] = rolesAry[i].Trim();
      // add all trimmed roles
private void InitProperties(){
   // get reference to all attributes of XmlElement
   XmlAttributeCollection attributes = m_nodeSetting.Attributes;
   m_properties = new Dictionary<string,string>();
   // and add them to a Dictionary<,>
   foreach (XmlAttribute attrib in attributes)
      m_properties.Add(attrib.Name, attrib.Value.ToString());

The properties code simply returns the value from the corresponding attribute:

public override string Name {
   get { return m_nodeSetting.GetAttribute(“Name"); }
public override string ID{
   get { 
      string id = m_nodeSetting.GetAttribute(“ID");
      if (string.IsNullOrEmpty(id))
         id = base.ID;
      return id;

The code that creates the CustomMenuCreator component is shown below. It uses Reflection and helper methods from class WTHelper to create the MenuCreator class instance.

private string m_customCreatorClassname = string.Empty;
private IWTCustomMenuCreator m_customCreator = null;
public IWTCustomMenuCreator CustomMenuCreator {
   get {
      // if menucreator is null and menucreator class name is empty
      if (m_customCreator == null && 
         m_customCreatorClassname ==  string.Empty) {
         // read CustomMenuCreator attribute 
         IWTCustomMenuCreator custCreator = null;
         m_customCreatorClassname = 
        if (m_customCreatorClassname!=string.Empty)
           // try to create the instance of CustomMenuCreator
           // if class name is not specified correctly 
           // or not class definition not available 
           // this can fail, so we wrap in a try ... catch statement
           try {
              custCreator = (IWTCustomMenuCreator)WTHelper.            
           catch (Exception ex) {
             // if fail, log the error 
                "Error creating custom menu creator for class {0}",
             m_customCreatorClassname), ex);
             custCreator = null;
        m_customCreator = custCreator;
    return m_customCreator;

Now, to put things together, you need to create a complete data structure for the menu definition, which will then create the actual menu. Creating the menu is the job of the menu controller, implemented by the WTMenuDefinitionController class. WTMenuDefinitionController exposes the static method InitMenuStructure, which receives the name of a menu configuration file as a parameter, and attempts to build the menu structure from the information in that file.

The configuration file gets loaded into an XmlDocument. It passes the root node (the DocumentElement), to the LoadMenuConfiguration method that builds the menu definition structure. The returned value is a generic List<IWTMenuEntryDefinition>, which contains the actual menu definition structure used to build the usercontrol menu component. LoadMenuConfiguration receives two more parameters, extracted from the attributes of the MainMenu root node, by the helper class WTMenuRootDefinitionXml: the default access mode for menu entries if no other security restriction applies, and the name of the module implementing security access rights for menu items.

Listing 2 shows the LoadMenuConfiguration method.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date