Form Menus


Form Menus

As interesting as forms themselves are ”with their lifetime, adornments, transparency settings, and input options ”they're all the more interesting with controls on them. But before we get into managing a form's controls in general, we need to take a quick look at menus, which have special support in WinForms. Not only does VS.NET have a special Menu Designer (as shown in Figure 2.7), but also, unlike every other control, a Form can show only one main menu at a time, as stored in the Form.Menu property (which is of type MainMenu).

Figure 2.7. The VS.NET Menu Designer

Although you are limited to a single main menu showing on a form at a time, you can switch menus at run time to your heart's content by setting the Form.Menu property:

 void showMenu1Button_Click(object sender, EventArgs e) {  this.Menu = this.mainMenu1;  } void showMenu2Button_Click(object sender, EventArgs e) {  this.Menu = this.mainMenu2;  } void showNoMenuButton_Click(object sender, EventArgs e) {  this.Menu = null;  } 

In fact, if you drag multiple MainMenu components from the Toolbox onto the form, you can select each one and edit it separately, but you'll need to set the form's Menu property to pick which one to start with. No matter which menu you choose to designate as the form's main menu (or even if you choose none at all), menus themselves are only containers for items modeled via the MenuItem class.

In fact, menus and menu items are both containers. The MainMenu class has a MenuItems collection that contains zero or more MenuItem objects. This makes up the list of items across the top of the menu, such as File, Edit, and Help. Each of these MenuItem objects in turn has its own MenuItems collection, which contains the next level of items ”for example, File Save, File Recent Files, File Exit. Anything below that level shows up as a cascading menu of items, such as File Recent Files foo.txt.

The Menu Designer takes the menu structure you lay out and generates the code to populate the menu items in InitializeComponent. For example, using the Designer to create the File Exit and Help About menu items as shown in Figure 2.7 results in code that looks like this (and really makes you appreciate the Designer):

 private void InitializeComponent() {  this.mainMenu1 = new System.Windows.Forms.MainMenu();   this.fileMenuItem = new System.Windows.Forms.MenuItem();   this.fileExitMenuItem = new System.Windows.Forms.MenuItem();   this.helpMenuItem = new System.Windows.Forms.MenuItem();   this.helpAboutMenuItem = new System.Windows.Forms.MenuItem();  ...   // mainMenu1  this.mainMenu1.MenuItems.AddRange(   new System.Windows.Forms.MenuItem[] {   this.fileMenuItem,   this.helpMenuItem});  // fileMenuItem   this.fileMenuItem.Index = 0;  this.fileMenuItem.MenuItems.AddRange(   new System.Windows.Forms.MenuItem[] {   this.fileExitMenuItem});   this.fileMenuItem.Text = "&File";  // fileExitMenuItem   this.fileExitMenuItem.Index = 0;  this.fileExitMenuItem.Text = "&Exit";  // helpMenuItem   this.helpMenuItem.Index = 1;  this.helpMenuItem.MenuItems.AddRange(   new System.Windows.Forms.MenuItem[] {   this.helpAboutMenuItem});   this.helpMenuItem.Text = "&Help";  // helpAboutMenuItem   this.helpAboutMenuItem.Index = 0;  this.helpAboutMenuItem.Text = "&About...";  // Form1   ...  this.Menu = this.mainMenu1;  ... } 

The MenuItem class has the following design-time properties and events:

 class MenuItem : Menu, IComponent,  IDisposable {   // Properties   public bool Checked { get; set; }   public bool DefaultItem { get; set; }   public bool Enabled { get; set; }   public bool MdiList { get; set; }   public int MergeOrder { get; set; }   public MenuMerge MergeType { get; set; }   public bool OwnerDraw { get; set; }   public bool RadioCheck { get; set; }   public Shortcut Shortcut { get; set; }   public bool ShowShortcut { get; set; }   public string Text { get; set; }   public bool Visible { get; set; }   // Events   public event EventHandler Click;   public event DrawItemEventHandler DrawItem;   public event MeasureItemEventHandler MeasureItem;   public event EventHandler Popup;   public event EventHandler Select; } 

The major things you'll want to focus on are the Checked and RadioCheck properties (which mark an item as chosen), the Enabled and Visible properties (which determine whether the item can be chosen or whether it will be shown), the Shortcut property (which allows you to assign a keyboard shortcut to a menu item, such as Ctrl+S for Save), and the Text property, which is what's shown to the user . A Text property that includes an "&" (ampersand) will underline the next character; for example, "&Save" will show as " S ave", thereby providing a visual cue for keyboard menu navigation via the Alt key. Typing "-" (hyphen) as the Text in the Menu Designer will create a separator between groups of related menu items. The menu merging and MdiList properties are MDI- related , and I discuss them later in this chapter.

Of course, the Click event handler is the big celebrity in the menu item list of events because it gets fired when the user clicks on a menu item:

 void fileExitMenuItem_Click(object sender, EventArgs e) {   this.Close(); } void helpAboutMenuItem_Click(object sender, EventArgs e) {   MessageBox.Show("Ain't menus cool?", "About..."); } 

Context Menus

Just as a form can show at most one main menu, a form (or a control) can show at most one context menu, as managed via the ContextMenu property. Unlike the MainMenu property, which is of type MainMenu, the ContextMenu property is of type ContextMenu, and you'll need to make sure to drag the correct class from the Toolbox. A ContextMenu is also a collection of menu items, but unlike MainMenu objects, ContextMenu objects have no concept of items "across the top." Context menus are always vertical at every level, and this is reflected in the Context Menu Designer, as shown in Figure 2.8.

Figure 2.8. Context Menu Designer

In the case of context menus, the Designer always shows "Context Menu" at the top level, and items can only fall under that. However, everything else is the same: Each ContextMenu object has a MenuItems collection filled with MenuItem objects, all with the same properties and events.

The one remaining difference between MainMenu objects and ContextMenu objects is that controls also have a ContextMenu property, whereas only a form has a MainMenu property.

Although many controls have their own context menus ”for example, a TextBox has things such as Copy and Paste in its context menu ”you can replace a control's built-in context menu by setting the ContextMenu property of the control. As a rule, most of the operations available from any control's context menu are also available as methods on the control. This means that you can replace the context menu on a control but still provide the operations that the control's menu would provide, implementing those options by sending the command to the control itself:

 void copyMenuItem_Click(object sender, EventArgs e) {   textBox1.Copy(); } 


Windows Forms Programming in C#
Windows Forms Programming in C#
ISBN: 0321116208
EAN: 2147483647
Year: 2003
Pages: 136
Authors: Chris Sells

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net