Unified Event Handling

The majority of toolbar buttons act as shortcuts to menu items, so it makes sense to handle equivalent clicks with a single event handler. Unfortunately, Windows Forms does not provide a direct way of doing this. However, it is fairly easy to arrange such a scheme. We can write an event handler for the toolbar that locates the appropriate menu item and then calls its event handler.

All we need is some way of associating toolbar buttons with menu items. For this, we can use a class provided by the .NET Framework class libraries called System.Collections.Hashtable—it is designed to store associations between objects. We can use this to remember which toolbar buttons are equivalent to which menu items. Although the Designer cannot store these associations in a hash table for you automatically, it only requires a small amount of code in your form’s constructor. The following is the necessary C# code:

// Hashtable to associate buttons with menu items

private Hashtable toolbarButtonToMenu;

public MyForm()

{

    InitializeComponent();



    // Create hash table

    toolbarButtonToMenu = new Hashtable();



    // Associate ToolBarButtons with MenuItems

    toolbarButtonToMenu(toolBarFileNew)    = menuFileNew;

    toolbarButtonToMenu(toolBarFileOpen)   = menuFileOpen;

    toolbarButtonToMenu(toolBarEditCopy)   = menuEditCopy;

    toolbarButtonToMenu(toolBarEditCut)    = menuEditCut;

    toolbarButtonToMenu(toolBarEditPaste)  = menuEditPaste;

    toolbarButtonToMenu(toolBarEditDelete) = menuEditDelete;

}

The following is its VB equivalent:

' Hashtable to associate buttons with menu items

Private toolbarButtonToMenu As HashTable



Public Sub New()



    InitializeComponent()



    ' Create hash table

    toolbarButtonToMenu = New Hashtable()



    ' Associate ToolBarButtons with MenuItems

    toolbarButtonToMenu(toolBarFileNew)    = menuFileNew

    toolbarButtonToMenu(toolBarFileOpen)   = menuFileOpen

    toolbarButtonToMenu(toolBarEditCopy)   = menuEditCopy

    toolbarButtonToMenu(toolBarEditCut)    = menuEditCut

    toolbarButtonToMenu(toolBarEditPaste)  = menuEditPaste

    toolbarButtonToMenu(toolBarEditDelete) = menuEditDelete

End Sub

This creates a hash table called toolbarButtonToMenu, which associates toolbar buttons (toolBarFileNew, toolBarFileOpen, etc.) with their respective menu items (menuFileNew, menuFileOpen, etc.). With this association in place, the following C# code can be placed in the toolbar’s ButtonClick handler to direct all clicks on toolbar buttons to the appropriate menu item:

private void toolBar_ButtonClick(object sender, 

    System.Windows.Forms.ToolBarButtonClickEventArgs e)

{

    MenuItem mi = toolbarButtonToMenu[e.Button] as MenuItem;

    if (mi != null)

        mi.PerformClick();

}

The corresponding VB code is:

Private Sub toolBar_ButtonClick(sender As Object, _ 

      e As System.Windows.Forms.ToolBarButtonClickEventArgs) _

      Handles toolBar.ButtonClick



   Dim mi As MenuItem = toolbarButtonToMenu(e.Button) 

   If Not mi Is Nothing Then

      mi.PerformClick()

   End If

End Sub

This simply looks in toolbarButtonToMenu to see if the button that was clicked has an associated menu item. If it does, it uses the MenuItem class’s PerformClick method, which generates a Click event on that item. This will then be handled by that menu item’s click handler.

So with this code in place, clicking on a toolbar button will cause the associated menu item’s Click event to be raised, allowing you to handle these two events with a single event handler.

Get .NET Windows Forms in a Nutshell now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.