Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All

Walkthrough: Switching Windows Forms Menu Structures Based on Application State

Visual Studio .NET 2003

Your application can present different menus for different contexts (or different application states). It is possible to have many MainMenu objects, each of which presents different menu choices to the user. By having a number of MainMenu objects to present the correct menu structure to the user, you can handle the varying states of your application as users interact with it.

In this procedure, you will create a menu structure for when the application first opens and there is no file or data for the user to interact with. Thus, the application will have only a traditional File menu with New, Open, and Exit commands. When the user selects either the New or Open menu item, it triggers a change in application state (for demonstration purposes in the following example, a message box is shown as a visual aid; no actual files are opened or created). At this point, a second menu structure is shown, with additional menu items (Close and Save) that target an application that has data or a file loaded.

Creating a Menu at Design Time

In the following steps, you will design a Windows application, in the Windows Forms Designer, that switches menu structures.

To create a menu at design time

  1. Drag a MainMenu component from the Toolbox to the form.
  2. In the Menu Designer, create a top-level menu item with the Text property set to &File, and three submenu items with the Text properties set to &New, &Open, and E&xit, in that order. For details, see Adding Menus and Menu Items to Windows Forms.
  3. In the Windows Forms Designer, click the form (Form1.vb, Form1.cs, or Form1.h) to give it focus. In the Properties window, ensure that the Menu property is set to the menu you have just created (MainMenu1 in Visual Basic or mainMenu1 in Visual C# or Visual C++, unless you have given it a unique name).

To hook up the events

  1. Create a multicast event handler called MenuSelect for the New and Open menu items. You need to add references to the event handler in the form initialization function for Visual C# or Visual C++.
    // C#
    menuItem2.Click += new System.EventHandler(this.MenuSelect);
    menuItem3.Click += new System.EventHandler(this.MenuSelect);
    
    // C++
    menuItem2->Click += new System::EventHandler(this, MenuSelect);
    menuItem3->Click += new System::EventHandler(this, MenuSelect);
    

    This is a multicast event handler because it will handle the Click events for both menu items. For details, see Connecting Multiple Events to a Single Event Handler in Windows Forms.

  2. Enter the following code in the MenuSelect event handler:
    ' Visual Basic
    Private Sub MenuSelect(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItem2.Click, MenuItem3.Click
       MessageBox.Show("A file has been opened.", "Instead of a new file, here's a message box.")
       LoadSecondMenu()
    End Sub 
    
    // C#
    private void MenuSelect(object sender, System.EventArgs e)
    {
       MessageBox.Show("A file has been opened.", 
          "Instead of a new file, here's a message box.");
       LoadSecondMenu();
    }
    
    // C++
    private:
      System::Void MenuSelect(System::Object *  sender,
        System::EventArgs *  e)
      {
        MessageBox::Show("A file has been opened.",
          "Instead of a new file, here's a message box.");
        LoadSecondMenu();
      }
    
    Note   
    LoadSecondMenu
    will be a procedure you write to switch the menu when either of the menu items (New or Open) is clicked.
  3. In the Code Editor, create a method, similar to the following, to set the form's menu to the second MainMenu component you created:
    ' Visual Basic
    Private Sub LoadSecondMenu()
       Me.Menu = MainMenu2
    End Sub
    
    // C#
    private void LoadSecondMenu(){
       this.Menu = mainMenu2;
    }
    
    // C++
    private:
      System::Void LoadSecondMenu()
      {
        this->Menu = mainMenu2;
      }
    
    Note   
    MainMenu2
    refers to a MainMenu component that you add to the form later on.

To copy the menus for the second set

  1. In Solution Explorer, right-click the form name and choose View Designer on the shortcut menu.
  2. In the component tray, click the icon for the MainMenu component, so that it has focus in the form.
  3. In the Menu Designer, click the top-level menu item you created (File). Right-click and choose Copy.
    Note   This makes a copy of the top-level menu item and all of its submenu items.
  4. Drag another MainMenu component from the Toolbox to the form.
  5. In the Menu Designer, right-click the "Type Here" area and choose Paste.

    The menu items you previously selected from the first MainMenu component are pasted into the second.

  6. In the Menu Designer, right-click the area to the left of the Exit menu item and choose Insert New. Do this again, so that you have inserted two new menu items.
  7. Set the Text property of these two new menu items to &Close and &Save, in that order, either in the Properties window or by clicking the item and typing in the space provided.

To test the application

  • Debug the application and press F5 to run it. For details about debugging, see Debugging Basics.

    The form has a menu that contains File, New, Open, and Exit menu items. Clicking New or Open raises an event, which is handled by the MenuSelect event handler. This method shows a message box and changes the application state. The application state change is indicated by the addition of two menu items, Close and Save.

Instead of using the above procedure, you can create the entire application in code. While this forgoes the ease of using the Windows Forms Designer, some developers may find this method more appealing.

Creating a Menu Programmatically

In the following steps, you will design a Windows application, the same as the one above, exclusively in code that switches menu structures.

To create a menu programmatically

  • In a method, create an instance of the MainMenu component with MenuItem objects corresponding to the application state.

    The following example has one MainMenu object for when the user first opens the application; it has only a traditional File menu with New, Open, and Exit commands. Additionally, the code below uses an overloaded Add method that creates menu items and associated event handlers with them. Wiring event handlers dynamically is an easy way to signal to the application that clicking either the New or Open menu command should trigger a change in the application state.

    ' Visual Basic
    ' Create a MainMenu object and a MenuItem object.
    Private mmAppStart as MainMenu
    Private miFile as MenuItem
    Public Sub AppStartMenu()
       ' Create an instance of the MainMenu object.
       mmAppStart = new MainMenu
    
       ' Create a top-level menu item and two menu items. Use this
       ' overloaded constructor that takes an event handler
       ' (MenuSelect) so that later, you can cause the menu selection 
       ' to change the application state.
       miFile = New MenuItem("&File", New System.EventHandler (AddressOf Me.MenuSelect))
       miFile.MenuItems.Add("&New", New System.EventHandler (AddressOf Me.MenuSelect))
       miFile.MenuItems.Add("&Open", New System.EventHandler (AddressOf Me.MenuSelect))
       miFile.MenuItems.Add("&Exit")
    
       ' Add the top-level menu item to the MainMenu component 
       ' and set the MainMenu component to be the form's menu.
       mmAppStart.MenuItems.Add(miFile)
    
       ' Set the form's menu to the menu you have just created.
       Me.Menu = mmAppStart
    End Sub
    
    // C#
    // Create a MainMenu object and a MenuItem object.
    MainMenu mmAppStart;
    MenuItem miFile;
    public void AppStartMenu(){
       // Create an instance of the MainMenu object.
       mmAppStart = new MainMenu();
    
       // Create a top-level menu item and two menu items. Use this
       // overloaded constructor that takes an event handler
       // (MenuSelect) so that later, you can cause the menu selection
       // to change the application state.
       miFile = new MenuItem("&File", new EventHandler(MenuSelect));
       miFile.MenuItems.Add("&New", new EventHandler(MenuSelect));
       miFile.MenuItems.Add("&Open", new EventHandler(MenuSelect));
       miFile.MenuItems.Add("&Exit");
    
       // Add the top-level menu item to the MainMenu component 
       // and set the MainMenu component to be the form's menu.
       mmAppStart.MenuItems.Add(miFile);
    
       // Set the form's menu to the menu you have just created.
       this.Menu = mmAppStart;
    }
    
    // C++
    // Create a MainMenu object and a MenuItem object.
    private: System::Windows::Forms::MainMenu *  mmAppStart;
    private: System::Windows::Forms::MenuItem *  miFile;
    
    private:
      void AppStartMenu()
      {
        // Create an instance of the MainMenu object.
        mmAppStart = new System::Windows::Forms::MainMenu();
    
        // Create a top-level menu item and two menu items. Use this
        // overloaded constructor that takes an event handler
        // (MenuSelect) so that later, you can cause the menu selection
        // to change the application state.
        miFile = new MenuItem(S"&File",
          new EventHandler(this, MenuSelect));
        miFile->MenuItems->Add(S"&New",
          new EventHandler(this, MenuSelect));
        miFile->MenuItems->Add(S"&Open",
          new EventHandler(this, MenuSelect));
        miFile->MenuItems->Add(S"&Exit",
          new EventHandler(this, MenuSelect));
    
        // Add the top-level menu item to the MainMenu component 
        // and set the MainMenu component to be the form's menu.
        mmAppStart->MenuItems->Add(miFile);
    
        // Set the form's menu to the menu you have just created.
        this->Menu = mmAppStart;
      }
    

To create the second set of menus

  1. In a second method, create a second instance of a MainMenu component with MenuItems that correspond to a second application state.

    For example, after the user has opened a file, you can expose commands to close it and save it. You can copy the original menu structure to use as a base for this menu structure, and to preserve the File, New, Open, and Exit menu items. For details, see Copying Items on Windows Forms Menus.

    ' Visual Basic
    ' Create the second MainMain object.
    Private mmFileLoadedMenu As MainMenu
    Public Sub FileLoadedMenu()
       mmFileLoadedMenu = New MainMenu()
       
       ' Clone the first menu with the CloneMenu method.
       mmFileLoadedMenu.MenuItems.Add(miFile.CloneMenu())
       
       ' Create two additional menu items related to the 
       ' application state.
       Dim mnuitemClose As New MenuItem("&Close")
       Dim mnuitemSave As New MenuItem("&Save")
       
       ' Add the two new menu items to the MenuItems collection of the 
       ' top-level menu item cloned above, using the Add method to
       ' specify their order within the collection by their index.
       mmFileLoadedMenu.MenuItems(0).MenuItems.Add((2), mnuitemClose)
       mmFileLoadedMenu.MenuItems(0).MenuItems.Add((3), mnuitemSave)
       
       ' Assign the newly-created MainMenu object to the form.
       Me.Menu = mmFileLoadedMenu
    End Sub
    
    // C#
    // Create the second MainMain object.
    private MainMenu mmFileLoadedMenu;
    private void FileLoadedMenu(){
       mmFileLoadedMenu = new MainMenu();
       
       // Clone the first menu with the CloneMenu method.
       mmFileLoadedMenu.MenuItems.Add(miFile.CloneMenu());
    
       // Create two additional menu items related to the 
       // application state.
       MenuItem mnuitemClose = new MenuItem("&Close");
       MenuItem mnuitemSave = new MenuItem("&Save");
       
       // Add the two new menu items to the MenuItems collection of the 
       // top-level menu item cloned above, using the Add method to
       // specify their order within the collection by their index.
       mmFileLoadedMenu.MenuItems[0].MenuItems.Add(2, mnuitemClose);
       mmFileLoadedMenu.MenuItems[0].MenuItems.Add(3, mnuitemSave);
       
       // Assign the newly-created MainMenu object to the form.
       Menu = mmFileLoadedMenu;
    }
    
    // C++
    // Create the second MainMenu object.
    private: System::Windows::Forms::MainMenu *  mmFileLoadedMenu;
    
    private:
      System::Void FileLoadedMenu()
      {
        mmFileLoadedMenu = new System::Windows::Forms::MainMenu();
    
        // Clone the first menu with the CloneMenu method.
        mmFileLoadedMenu->MenuItems->Add(miFile->CloneMenu());
        
        // Create two additional menu items related to the 
        // application state.
        MenuItem *mnuitemClose = new MenuItem(S"&Close");
        MenuItem *mnuitemSave = new MenuItem(S"&Save");
    
        // Add the two new menu items to the MenuItems collection of the 
        // top-level menu item cloned above, using the Add method to
        // specify their order within the collection by their index.
        mmFileLoadedMenu->MenuItems->Item[0]->MenuItems->Add(2,
          mnuitemClose);
        mmFileLoadedMenu->MenuItems->Item[0]->MenuItems->Add(3,
          mnuitemSave);
    
        // Assign the newly created MainMenu object to the form.
        this->Menu = mmFileLoadedMenu;
      }
    
  2. Add a line of code to the Form1 constructor, after the InitializeComponent method call, to call the AppStartMenu method created previously:
    ' Visual Basic
    AppStartMenu()
    
    // C#
    AppStartMenu();
    
    // C++
    AppStartMenu();
    
  3. Create an event handler within the class to switch the form's menu property to FileLoadedMenu.

    Instead of loading a file, the following code opens a message box to indicate a change in application state. For details, see MessageBox Class. The code then calls the AppStartMenu method that was written above, which creates the second MainMenu object and sets it to be the form's menu.

    ' Visual Basic
    Protected Sub MenuSelect(ByVal sender As Object, ByVal e As System.EventArgs)
       MessageBox.Show("A file has been opened.", "Instead of a new file, here's a message box.")
       FileLoadedMenu()
    End Sub
    
    // C#
    protected void MenuSelect(Object sender, System.EventArgs e){
       MessageBox.Show("A file has been opened.", 
          "Instead of a new file, here's a message box.");
       FileLoadedMenu();
    }
    
    // C++
    protected:
      System::Void MenuSelect(System::Object *  sender,
        System::EventArgs *  e)
      {
        MessageBox::Show("A file has been opened.",
          "Instead of a new file, here's a message box.");
        FileLoadedMenu();
      }
    

To test the application

  • Debug the application and press F5 to run it. For details about debugging, see Debugging Basics.

    The form has a menu that contains File, New, Open, and Exit menu items. Clicking New or Open raises an event, which is handled by the MenuSelect event handler. This method shows a MessageBox and changes the application state. The application state change is indicated by the addition of two menu items, Close and Save.

See Also

Introduction to the Windows Forms MainMenu Component | Menus in Windows Forms | Walkthrough: Creating Dynamic Context Menus on Windows Forms

Show:
© 2015 Microsoft