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  : Page 3

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

Defining the View: Interfaces for the Visual Portion of Menus

The visual parts of the menu system also use interfaces, which lets developers implement custom user interfaces for the user control representing the menu. The two interfaces that define the menu are IWTMenu and IWTMenuItem, as shown in Figure 2.

 
Figure 2. Visual Menu Interfaces: These interfaces define the visual part of the menu. IWTMenu defines the interface for a menu object, while IWTMenuItem defines the interface implemented by menu items.

IWTMenuItem exposes properties that define a menu item, described in Table 4.

Table 4. IWTMenu Properties: The IWTMenu interface defines these properties.
Property Description
bool Enabled {get; set;} If enabled, this menu item can be selected.
ResourceHandle Icon {get; set;} Holds the ResourceHandle of the menu icon to display.
string ID {get;} Returns the ID for the menu item.
IWTMenuEntryDefinition MenuEntryDefinition {get; set;} Reference to the IWTMenuEntryDefinition from which this menu item was created.
IWTMenu Parent {get;} Reference to parent menu (IWTMenu).
IWTModule LinkedModule {get; set;} Reference to the module launched by this menu item (IWTModule).



IWTMenu defines the interface to implement the menu. Its members are described in Table 5.

Table 5. IWTMenu Interface Members: The interface defines one property, two methods, and two events.
Property Description
IWTModule Host {get; set;} Holds a reference to the IWTModule instance into which this menu is loaded.
Methods Description
void InitMenu( List<IWTMenuEntryDefinition> menuDefinition); Creates the menu based on the menu definition.
bool DetachModule(IWTModule module) Detaches the module from the Menu Item that launched the module.
Event Description
event WTMenuEventHandler MenuItemClick This event fires when a user clicks a menu item.
event WTMenuEventHandler MenuItemAdded This event fires when a new item gets added to the menu.

Defining the Controller

At this point, you've seen the menu item definition classes representing the menu Model, and the interfaces for visual part of the menu system—Menus and Menu Items—that represent the View. The final component that joins everything together into a functional module is the Controller.

The controller is defined through the interface IWTMenuController, as shown in Figure 3.

 
Figure 3. Menu Controller Interface: The IWTMenuController interface defines a controller, which joins the Model and the View. You can see a list and description of the IWTMenuController interface members in Table 6.

Table 6. IWTMenu Interface Members: The table lists and describes the properties, methods, and events for the IWTMenu interface.
Property Description
IWTMenu Menu {get; set;} Holds a reference to the IWTMenu handled by the controller.
string MenuDefinitionFile {get; set;} Name of the menu configuration file used to build the menu. If this is specified, the controller builds the MenuEntryDefinition data structure and passes it to IWTMenu to create the menu's visual components.
List<IWTMenuEntryDefinition> MenuDefinition {get; set;} The controller can receive the menu definition data structure directly (which was created by some external component). In this case it uses this structure directly, and does not need the MenuDefinitionFile property.
IWTWorkplace TargetPanel {get; set;} The workplace (see this this earlier article) into which to load the module launched by a menu item.
Method Description
void ActivateMenu(); Call this method to activate the menu after setting a properties Menu, TargetPanel, and either a MenuDefinitionFile or a MenuDefinition.
Event Description
event WTMenuEventHandler MenuItemClick This event fires when a user clicks a menu item.
event WTMenuCancelEventHandler BeforeLaunchModule; This event fires just before launching the module associated with a menu item. You can use it to cancel the module launch.

Here's the ActivateMenu code:

public void ActivateMenu() { // ... // if there is no MenuDefinition property set, // and if menu configuration file exists // create menu definition structure if (m_menuDef==null && WTHelper.ConfigFileExists( m_configFile)) m_menuDef = WTMenuDefinitionController. InitMenuConfiguration(m_configFile); // and ask menu to build itself if (m_menuDef!=null) m_menu.InitMenu(m_menuDef); }

The set accessor for the Menu property unbinds the controller from the MenuItemClick event of a previous menu object (if one was set), and then binds to the MenuItemClick event, as shown below:

public IWTMenu Menu { get { return m_menu; } set { // if there was a previous menu assigned to controller // unbind from its MenuItemClick event if (m_menu!=value && m_menu!=null) m_menu.MenuItemClick -= new WTMenuEventHandler(HandlerMenuItemClick); // and bind to MenuItemClick event fired by the menu m_menu = value; if (m_menu!=null) m_menu.MenuItemClick += new WTMenuEventHandler(HandlerMenuItemClick); } }

The MenuItemClick handler code checks whether the selected MenuItem is associated with a linked module (if it is, then the module has already been loaded, and just needs to be reactivated. If there is an associated module, the event fires the BeforeLaunchModule, which gives developers an opportunity to write code to cancel the module load, and then launches the module (unless canceled).

If the module was already launched, it is just reactivated, and menuItem.LinkedModule.Refresh is called, which allows the module to refresh its status.

private void HandlerMenuItemClick(object sender, WTMenuEventArgs e) { WTMenuCancelEventArgs ce = new WTMenuCancelEventArgs(e.MenuItem); // if no linked module if (e.MenuItem.LinkedModule == null){ OnBeforeLaunchModule(sender, ce); if (!ce.Cancel) LaunchModule(e.MenuItem); } else ShowModule(e.MenuItem); OnMenuItemClick(sender, e); } private void ShowModule(IWTMenuItem menuItem) { m_host.ShowModule(menuItem.LinkedModule); // if linked module exists, just refresh it menuItem.LinkedModule.Refresh( new Webtools.Base.Events.WTCancelGenericEventArgs()); }

The LaunchModule method is the workhorse of the controller. It instantiates a module object and checks whether the module needs be launched in the same workplace where the menu itself is loaded. If so, it assigns the menu host as the parent module for the launched module; otherwise, the parent is set to null. Finally the controller calls the appropriate StartModule method. The module can implement either IWTModule, which provides a StartModule() method with no parameters, or IWTRunModule, which defines a StartModule method to receive a IWTMenuEntryDefinition parameter. The latter allows modules to get access to all the attributes defined in the menu configuration file. The important parts of the code are shown below (some code was removed for clarity):

private void LaunchModule(IWTMenuItem menuItem) { if (menuItem != null && menuItem.MenuEntryDefinition != null) { IWTMenu parentMenu = menuItem.Parent; // create module to be launched Type type = menuItem.MenuEntryDefinition.ModuleClassType; if (type != null) { object objModule = WTHelper.CreateObjectByReflectionFromType(type); IWTModule module = objModule as IWTModule; if (module != null) { // check if menu is hosted on a IWTModule, // which is loaded into the same Workplace where // the menu module should be loaded // if so, set the parent module of the menu module // as the host IWTModule for the menu // This letS the module pass the control back to // the menu when it is closed // If menu is loaded into different workplace, // pass null as parentModule IWTModule parentModule = menuItem.Parent.Host; if (!m_targetPanel.CheckModuleExists(parentModule)) parentModule = null; module = m_host.LoadModule(module, parentModule); // attach the started module to menu item and bind // to its Close event menuItem.LinkedModule = module; module.Close += new Webtools.Base.Events. WTCancelGenericEventHandler(Module_Close); } // if the module to be started implements IWTRunModule // call StartModule method with MenuEntryDefinition parameter, // which lets the module receive all extra properties defined // in the MenuItem definition entry from the configuration file IWTRunModule runModule = module as IWTRunModule; if (runModule != null) runModule.StartModule(menuItem.MenuEntryDefinition); else module.StartModule(); } else // if no type, hide all visible modules m_targetPanel.HideAllModules(); } }

The handler for Module_close simply detaches the module from the related menu item:

private void Module_Close(object sender, Webtools.Base.Events.WTCancelGenericEventArgs e) { IWTModule module = sender as IWTModule; if (module != null) m_menu.DetachModule(module); }



Comment and Contribute

 

 

 

 

 


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

 

 

Sitemap