Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

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

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.


advertisement

he MiniCMS system begun in the first article in this series needs to have flexible menu components. The menu system should be data driven—in this example, menus are created from a XML-formatted configuration file that defines each menu entry, specifies a name and optional image for each menu, and supports submenus to any number of levels.

A flexible menuing framework should have the following characteristics:

  • The system should handle menu item selection automatically and (when appropriate) launch specific modules, without developers having to write any code. At the same time, developers should be able to override this default behavior and be able to fire a custom event handler for any menu item.
  • The menu system should integrate with the security module to control access to menu items and related modules.
  • In addition to populating menus in a data-driven manner, developers should also be able to create menus dynamically, for example, to create Favorites, or Most Recently Used (MRU) submenus at runtime. For Content Management Systems (CMSs) the framework needs to be able to dynamically create part of the menu structure based on content added by users, and plug that into the main menu.
  • The menu system should allow developers to specify entry points where dynamic menus will get attached as submenus (such as a Favorites menu), and also define placeholders—which can get replaced at runtime by dynamic menus.
  • To support a wide diversity of user interfaces, the menu system should be visually flexible, to allow a custom look-and-feel that fits with overall application design.
  • The menu system should be defined using interfaces to prevent binding the implementation to specific existing controls and allow future enhancements or implementation changes.

This article shows how to implement a menu framework that has these desirable characteristics using the Model-View-Controller (MVC) pattern. That pattern lets you separate the actual menu definition structure (representing the Model), from the concrete visual implementation containing user interface elements that represent the View, and from the menu Controller, which creates the connection between the Model and the View. Using this approach, developers can implement whatever View is required to accommodate a custom look-and-feel, without changing the menu definition or the controller.



This article walks you through the menuing framework, describing the interfaces for the Model, View, and Controller. A follow-up article will delve deeply into defining and programming a complete custom working menu system.

Implementing the Model: Menu Definition

The various properties and a single method of a menu item are specified through the IWTMenuEntryDefinition interface . This interface defines all the elements needed to create a menu item, but does not define the menu item itself.

Table 1 shows the properties and methods:

Table 1. IWTmenuEntryDefinition Interface: The table shows the properties and methods exposed by the IWTmenuEntryDefinition interface.
Property Description
string Name { get; } The name or label displayed in the menu.
string IconName {get;} File name or resource name for the menu icon. This can be the name of a JPG, GIF, or PNG file located in Icons or Images resource folders as configured in your Visual WebGUI project (see Create and Configure the Project: Directories), or in the assembly that contains the module the menu item launches.
ResourceHandle Icon {get;} Returns the actual icon for menu as a ResourceHandle, which can be assigned to any Visual WebGUI object that exposes an Image property.
ExecutionMode ExecutionMode {get;} Specifies the execution mode where the menu item is available. Can be Web (for native Visual WebGUI applications) or Client (for desktop Visual WebGUI applications).
string ID {get;} Lets you specify an optional ID for the menu entry.
bool HasProperties {get;} Determines whether the menu entry definition contains additional properties. See Properties below for more information.
Dictionary<string, string> Properties {get;} Properties are key/value pairs of type string that can store additional data for a menu item. For example, a menu entry that starts a Web Browser module, might have a property namedURL, associated with the URL the browser should navigate to when loaded.
bool HasRoles {get;} Returns true if user Groups or Roles are specified for the menu. This lets the menu system integrate easily into applications that work with user groups or roles-based authentication, such as ASP.NET membership. Note, however, that the menu system is not bound to any particular security framework, and does not enforce any security restrictions. Instead, it simply provides hooks that developers can use to integrate the menus with any security or authentication framework
List<string> Roles { get; } List of roles or user groups specified for a menu entry.
List<IWTMenuEntryDefinition> ChildMenus { get; } Contains a list of menu entry definitions for child menus.
bool HasChildMenus { get; } This value is true if the menu entry contains child submenu definitions.
string ModuleClassName { get; set; } Specifies the class name of the module launched by the menu.
Type ModuleClassType { get; } Returns a type used to create the module launched by the menu. This is created from the ModuleClassName using Reflection.
Method Description
bool PropertyExists(string propName); Returns true when the specified property exists in the menu entry properties list.

To associate menu items with specific modules, the framework uses the class name specified in ModuleClassName to instantiate the corresponding object at runtime, through Reflection. The supplied ModuleClassName must comply with the following naming conventions:

  • The default namespace should match the assembly name where the class is defined
  • The class name can be fully qualified with the default namespace, or can have default namespace stripped. At runtime, the framework will check if default namespace is part of class name and if not, will create the fully qualified class name by joining the assembly name with the class name. For example, the following entries are equivalent:

Type= "SampleModules.TestTreeHostModule, MiniCMS"
Type= "MiniCMS.SampleModules.TestTreeHostModule, MiniCMS" 

The first form is preferred for simplicity.

The framework contains a Webtools.Base.Helpers.WTHelper class that provides static methods to create types and objects through reflection either from the class name or directly from the AppSettings keys

 
Figure 1. 1 Menu Definition Interface and Classes: Together, these interfaces and classes form the basic functionality of the menuing system.

Figure 1 shows the interface and classes used by the menuing system. The WTMenuEntryDefinitionBase class implements the base functionality for defining menu entries, and WTMenuEntryDefinitionXml extends that by supporting menu definitions based on entries specified in an XML-formatted menu configuration file.

WTMenuEntryDefinitionBase is an abstract class that contains concrete implementations for those members of the IWTMenuEntryDefinition interface that are unlikely to change in derived classes. One such member is the Icon property, which must return a ResourceHandle for the icon, either by searching for an image embedded as a resource in the assembly that contains the module launched by the menu, or in the Icons or Images resource folders as configured in the Visual WebGui project (see the earlier article Create and Configure the Project: Directories). Here's the Icon property implementation:

public virtual ResourceHandle Icon {
   get {
      ResourceHandle icon = null;
      string iconName = IconName;
      // if there is icon name
      if (!string.IsNullOrEmpty(iconName)) {
         // configure it as resource name 
         // (e.g from path\file name format to dot format)
         // filename Images\Users.png will became Images.Users.png
         string iconResourceName = 
            WTHelper.FileNameAsEmbeddedResourceResource(iconName);
      // try to find the type of module launched by menu
      // if no module is specified, look for resource icon 
      // in current assembly
      Type moduleClass = ModuleClassType;
      if (moduleClass == null)
         moduleClass = this.GetType();
      // if image exists as embeded resource, return handle to it
      if (WTHelper.FileExistsAsEmbeddedResource(moduleClass, iconName))
         icon = new AssemblyResourceHandle(moduleClass, 
            iconResourceName);
      // otherwise try to look for it either in Icons resource filder 
      else if (WTHelper.IconExists(iconName))
         icon = new IconResourceHandle(iconResourceName);
      // or in Images resource filder
      else if (WTHelper.ImageExists(iconName))
         icon = new ImageResourceHandle(iconResourceName);
      }
      // if the icon was not found, use default menu icon 
      if (icon == null)
         icon = WTMenuEntryDefinitionBase.DefaultMenuIcon;
      return icon;
   }
}

The DefaultMenuIcon method (see Listing 1) called toward the end of the preceding method returns a default Icon as a resource handle. This strategy provides a standard default icon for all menu items without a custom icon specification.

The rest of the properties defined in WTMenuEntryDefinitionBase are basic field accessors.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap