Create a Dynamic Menu Using C#

Create a Dynamic Menu Using C#

Introduction

There have been articles on the technique of creating MRU (Most Recently Used) file menus in Visual Studio environment, for example http://www.codeguru.com/csharp/csharp/cs_misc/designtechniques/article.php/c15571. In my recent project, I need not only to create a MRU file menu, but also other menus that are dynamically created. For example, a user-customizable tools menu, help menu, and so forth. This article generalizes the way of creating a MRU menu to introduce the concept of a Dynamic Menu, which is created dynamically at application execution time.

One thing in common in the menus my application needs to create is that each dynamic menu item is associated with data. In the case of a MRU file menu item, it is the file path to be opened, and in the case of a tools menu item, it is the path of an application to be invoked. When it comes to a user-customizable help menu, it is a document file of various types to be displayed. In all these cases, the data associated with a menu item is of string type. It does not prevent you to make it an object to be more general. The MenuItem class in System.Windows.Forms namespace has the object type property Tag that can be used to store user data. You can utilize this placeholder to store the data of dynamic menu items, but I prefer to derive a class from the MenuItem item class. This allows you to further expand this class in the future when needed, and also it makes the code easy to understand. In my example code, the derived class is named DynamicMenuItem. To simplify the code, I make this data member string type, which meets the needs of MRU file menu and tools menu.

To add dynamic menu items to a menu list, a dynamic menu manager class is designed. The manager class controls the type of dynamic menu list and the way to add a menu item to the menu list that I will explain in detail.

The Dynamic Menu Item Class

As has been discussed, the dynamic menu item class is derived from MenuItem class.

public class DynamicMenuItem : MenuItem
{
   private string _data;

   // Dynamic menus information, i.e. menu text and menu data are
   // normally retrieved from some source like a database or
   // Registry. Putting them into an array of DynamicMenuItemTextData
   // struct will make it convenient to prepare for creating a group
   // of dynamic menu items through the dynamic menu manager.
   public struct DynamicMenuItemTextData
   {
      string _menuText;
      string _menuData;

      public string MenuText
      {
         get { return _menuText; }
         set { _menuText = value; }
      }
      public string MenuData
      {
         get { return _menuData; }
         set { _menuData = value; }
      }
      public DynamicMenuItemTextData(string menuText,
                                     string menuData)
      {
         _menuText = menuText;
         _menuData = menuData;
      }
   }

   public string Data
   {
      get { return _data; }
      set { _data = value; }
   }

   public DynamicMenuItem(string text, string data,
                          System.EventHandler eventHandler)
      : base(text)
   {
      _data = data;
      // Add menu item clicked event handler when it is created.
      this.Click += new System.EventHandler(eventHandler);
   }
}

Anchor Menu Items, Dynamic Menu Types, and Dynamic Menu Manager

An anchor menu item is an menu item added at menu design time. The purpose of an anchor is to position the dynamic menu item list. The dynamic menu item list may be at the same level of the anchor, which I call the inline dynamic menu item list. The list is immediately below the anchor. The dynamic menu item list also can be a submenu of the anchor. In the case of an inline menu list, the anchor should be invisible. The separator immediately above it or below it should also be invisible until there is one dynamic menu item added. If the menu list forms a submenu of the anchor, the anchor is visible but is disabled until there is one dynamic menu item added. The separator is always visible in this case. The type of dynamic menu type and the visibility of the anchor is controlled by DynamicMenuMgr. When a new dynamic menu item is added to the menu list, it can be put on top of the list or be appended to the list. The manner of adding a new menu item is also controlled by DynamicMenuMgr.

When a new menu item is added, DynamicMenuMgr is responsible for registering the menu item click event handler. All the dynamic menu items share a common event handler. In my demo code, the event handler displays the data stored in the menu item being clicked in a message box.

private void MenuItemClick(object sender, EventArgs e)
{
   DynamicMenuItem item = (DynamicMenuItem)sender;
   MessageBox.Show(item.Data);
}

More by Author

Must Read