RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Building Robust UIs in Mono with Gtk# : Page 3

Learn to use the native Gtk# GUI toolkit to build Mono-based desktop applications today.

The World of Widgets
In terms of Gtk#, a "widget" is a user interface element that can be contained within a host such as a main window or dialog. The Gtk namespace defines numerous widgets whose overall usefulness should be quite familiar to those of you who have worked with Windows Forms.

As you would expect, there are Button widgets, AboutDialog, Calendar, Clipboard, FileChooser, Label, and Menu widgets as well as many others. The Gtk.Widget class is the parent to each widget type. As any good base class does, Widget provides a polymorphic interface to derived types. I'll use various properties, methods, and events of the Widget type in the remainder of the article; you can explore the details using MonoDoc.

Building a Menu System
Any main Window worth its salt will support a menu system to let users perform common operations (save data, exit the application, display dialogs, etc). To build a menu system with Gtk#, you need three core widgets (see Table 4).

Table 4. Menu Construction Widgets: The table lists the Gtk# programming primitives used in constructing menus.
Menu System Widget Description
MenuBar Represents the entire menu structure (top most items, sub-items, embedded icons, etc).
Menu Represents a top most item within the MenuBar.
MenuItem Represents the top most item and the related sub menus.

Building a menu system boils down to a set of fairly predictable steps:

  1. Allocate a MenuBar object to represent the entire menu system.
  2. Create a Menu object to represent the entirety of each topmost menu.
  3. Add MenuItems to the appropriate Menu object.
  4. Add the Menu object to the MenuBar
After establishing the overall menu system, you need to add it to the Window's widget collection (typically within an Hbox or VBox widget, described in just a moment). To illustrate the basic process, consider the C# class definition in Listing 1 (see the MenuWindow.cs file in the downloadable sample code).

The real meat of the class in Listing 1 is the CreateMenu() method called from the window's constructor. Notice that when creating a MenuItem object, you may specify an underscore (_) character before a particular letter of the menu title. Doing that causes Windows to associate that letter with a shortcut key, making the menu item accessible from the keyboard by pressing it in combination with the Alt key.

Figure 4. A Basic Menu: The figure shows a new version of the simple window that includes a basic Gtk# menu system.
Author's Note: For simplicity, the menu-centric widgets have been declared as local variables, rather than as member variables of the MainWindow class type. If you wish to interact with these widgets from other aspects of the Window derived type (for example to check or disable menu items from code), this would be an obvious improvement.

The only part of Listing 1 that might give you pause is the use of the VBox type. Again, I'll discuss this type in more detail shortly; for now, it's sufficient to know that you use the VBox type to position a widget within a host container. Figure 4 shows the menu system in action.

Because the code in Listing 1 handles the Activated event for the Quit menu item, the application terminates when you select File | Quit:

   menuItem.Activated += new EventHandler(FileQuit_Activated);
In addition to the core menu-centric widgets shown in Table 3, Gtk# provides many additional types to create extremely elaborate menu systems. For example the RadioMenuItem type represents a set of radio buttons embedded within a menu, while CheckMenuItem allows you to embed check boxes within a menu system. Furthermore, you can create Gtk# menu systems that support accelerator keys, menu separators, and custom images (as well as numerous 'stock' menu images).

The following code improves on the basic CreateMenu() method by adding ImageMenuItem and AccelGroup objects to provide a standard File | Quit icon and shortcut key.

   void CreateMenu()
      // MenuBar represents the entire whole of the menu system.
      MenuBar mainMenu = new MenuBar();
      // Now define an accelerator group.
      AccelGroup aGroup = new AccelGroup();
      // Build File menu item.
      Menu fileMenu = new Menu();
      MenuItem menuItem = new MenuItem("_File");
      menuItem.Submenu = fileMenu;
Figure 5. Updated File Menu: Here's the Gtk# menu after adding a stock image and an accelerator key to the Quit menu item.
// Build File | Exit menu Item. menuItem = new ImageMenuItem(Stock.Quit, aGroup); menuItem.Activated += new EventHandler(FileQuit_Activated); fileMenu.Append(menuItem); // Add the menu into a VBox and then add the VBox into the // Window's widget collection. VBox v = new VBox(); v.PackStart(mainMenu, false, false, 0); this.Add(v); }
In the preceding code, the ImageMenuItem constructor accepts a parameter value from the Stock type. The Stock class (as the name suggests) defines several built in UI elements including common icons, text messages, shortcut keys, etc. Figure 5 shows the newly updated menu system.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date