
- •brief contents
- •about this book
- •The Windows Forms namespace
- •Part 1: Hello Windows Forms
- •Part 2: Basic Windows Forms
- •Part 3: Advanced Windows Forms
- •Who should read this book?
- •Conventions
- •Action
- •Result
- •Source code downloads
- •Author online
- •acknowledgments
- •about .NET
- •Casting the .NET
- •Windows Forms overview
- •about the cover illustration
- •Hello Windows Forms
- •1.1 Programming in C#
- •1.1.1 Namespaces and classes
- •1.1.2 Constructors and methods
- •1.1.3 C# types
- •1.1.4 The entry point
- •1.1.5 The Application class
- •1.1.6 Program execution
- •1.2 Adding controls
- •1.2.1 Shortcuts and fully qualified names
- •1.2.2 Fields and properties
- •1.2.3 The Controls property
- •1.3 Loading files
- •1.3.1 Events
- •1.3.2 The OpenFileDialog class
- •1.3.3 Bitmap images
- •1.4 Resizing forms
- •1.4.1 Desktop layout properties
- •1.4.2 The Anchor property
- •1.4.3 The Dock property
- •1.5 Recap
- •2.1 Programming with Visual Studio .NET
- •2.1.1 Creating a project
- •Action
- •Result
- •2.1.2 Executing a program
- •Action
- •Result
- •2.1.3 Viewing the source code
- •View the code generated by Visual Studio .NET
- •Action
- •Result
- •2.2 Adding controls
- •2.2.1 The AssemblyInfo file
- •Action
- •Results
- •2.2.2 Renaming a form
- •Action
- •Result
- •2.2.3 The Toolbox window
- •Action
- •Result
- •2.3 Loading files
- •2.3.1 Event handlers in Visual Studio .NET
- •Action
- •Result
- •2.3.2 Exception handling
- •Action
- •Result
- •Action
- •Results and Comments
- •2.4 Resizing forms
- •2.4.1 Assign the Anchor property
- •Action
- •Result
- •2.4.2 Assign the MinimumSize property
- •Action
- •Result
- •2.5 Recap
- •Basic Windows Forms
- •Menus
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •3.3 Click events
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •3.5 Context menus
- •Action
- •Result
- •Action
- •Result
- •3.6 Recap
- •Status bars
- •4.1 The Control class
- •4.2 The StatusBar class
- •Action
- •Result
- •Action
- •Result
- •4.3.1 Adding panels to a status bar
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •4.5 Recap
- •Reusable libraries
- •5.1 C# classes and interfaces
- •5.2 Class libraries
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •5.3 Interfaces revisited
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •5.4 Robustness issues
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Common file dialogs
- •Action
- •Results
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •6.3 Paint events
- •Action
- •Result
- •Action
- •Result
- •6.4 Context menus revisited
- •Action
- •Result
- •Action
- •Result
- •6.5 Files and paths
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •6.6 Save file dialogs
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •6.7 Open file dialogs
- •Action
- •Result
- •Action
- •Result
- •6.8 Recap
- •Drawing and scrolling
- •7.1 Form class hierarchy
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •7.4 Panels
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Dialog boxes
- •8.1 Message boxes
- •Action
- •Result
- •Action
- •Result
- •8.1.4 Creating A YesNoCancel dialog
- •Action
- •Result
- •Action
- •Result
- •8.2 The Form.Close method
- •8.2.1 The relationship between Close and Dispose
- •Action
- •Result
- •8.3 Modal dialog boxes
- •Action
- •Result
- •Action
- •Result
- •8.3.2 Preserving caption values
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Basic controls
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •9.1.2 Creating a derived form
- •Action
- •Result
- •9.2 Labels and text boxes
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •9.3.6 Adding AlbumEditDlg to our main form
- •Action
- •Result
- •Action
- •Result
- •9.4 Recap
- •List controls
- •10.1 List boxes
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •10.2 Multiselection list boxes
- •10.2.1 Enabling multiple selection
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •10.3 Combo boxes
- •Action
- •Result
- •Action
- •Result
- •10.4 Combo box edits
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •10.5 Owner-drawn lists
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •More controls
- •Action
- •Result
- •Action
- •Result
- •11.2 Tab pages
- •Action
- •Result
- •Action
- •Result
- •11.3.1 Dates and times
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •11.5 Recap
- •A .NET assortment
- •12.1 Keyboard events
- •Action
- •Result
- •Action
- •Result
- •12.2 Mouse events
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •12.3 Image buttons
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •12.4 Icons
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •12.5 Recap
- •Toolbars and tips
- •13.1 Toolbars
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •13.4.2 Creating tool tips
- •Action
- •Result
- •Action
- •Result
- •Advanced Windows Forms
- •List views
- •14.2 The ListView class
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •14.2.3 Populating a ListView
- •Action
- •Result
- •Action
- •14.3 ListView columns
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •14.6 Recap
- •Tree views
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •15.3 Dynamic tree nodes
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •15.4 Node selection
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •15.5 Fun with tree views
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Multiple document interfaces
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •16.3 Merged menus
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •16.4 MDI children
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •16.5 MDI child window management
- •Action
- •Result
- •Action
- •Result
- •16.6 Recap
- •Data binding
- •17.1 Data grids
- •Action
- •Result
- •Action
- •Result
- •17.2 Data grid customization
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Odds and ends .NET
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •18.2 Timers
- •Action
- •Result
- •Action
- •Result
- •18.3 Drag and drop
- •Action
- •Result
- •Action
- •Result
- •18.4 ActiveX controls
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •18.5 Recap
- •C# primer
- •A.1 C# programs
- •A.1.1 Assemblies
- •A.1.2 Namespaces
- •A.2 Types
- •A.2.1 Classes
- •A.2.2 Structures
- •A.2.3 Interfaces
- •A.2.4 Enumerations
- •A.2.5 Delegates
- •A.3 Language elements
- •A.3.1 Built-in types
- •A.3.2 Operators
- •A.3.3 Keywords
- •A.4 Special features
- •A.4.1 Exceptions
- •A.4.2 Arrays
- •A.4.3 Main
- •A.4.4 Boxing
- •A.4.5 Documentation
- •.NET namespaces
- •B.1 System.Collections
- •B.2 System.ComponentModel
- •B.3 System.Data
- •B.4 System.Drawing
- •B.5 System.Globalization
- •B.6 System.IO
- •B.7 System.Net
- •B.8 System.Reflection
- •B.9 System.Resources
- •B.10 System.Security
- •B.11 System.Threading
- •B.12 System.Web
- •B.13 System.Windows.Forms
- •B.14 System.XML
- •Visual index
- •C.1 Objects
- •C.2 Marshal by reference objects
- •C.3 Components
- •C.4 Common dialogs
- •C.7 Event data
- •C.8 Enumerations
- •For more information
- •bibliography
- •Symbols
- •Index

to you, skip ahead and go read chapter 4. There we discuss owner-drawn status bar panels, which use a similar mechanism to that required for owner-drawn menus. In the meantime, the rest of us will move on to context menus.
3.5CONTEXT MENUS
While the creation of context menus requires a little extra effort by a programmer, they also improve the usability of an application greatly and should be seriously considered for any application. The ability of a user to right-click a control and instantly see a list of commands is a powerful mechanism that experienced users especially appreciate. Context menus are typically associated with a specific graphical control, but can also be brought up programmatically. As a result, context menus provide quick access to commands immediately relevant to what the user is currently trying to accomplish or understand.
Most controls in the System.Windows.Forms namespace have a ContextMenu property that specifies a ContextMenu object to associate with the control. Like the Menu property on Form objects, this setting can be changed dynamically to allow different context menus to display depending on the state of the control.
In this section we will add a context menu to our PictureBox control that will match the contents of the View menu. The contents and behavior of our context menu will be inherited from the View menu items. As you will see, our careful handling of these menus earlier in the chapter will make processing events for our context menu a snap. Figure 3.8 shows this context menu both before and after an image has been loaded by the user.
Figure 3.8 In both the main View menu and the context menu, the display options are disabled before an image is loaded.
CONTEXT MENUS |
97 |
3.5.1CREATING A CONTEXT MENU
We will begin by simply adding a new context menu to our application and associating it with the pbxPhoto control. The next section will discuss how to populate this menu with our existing menu items.
Set the version number of the application to 3.5.
|
|
ADD A CONTEXT MENU |
|
|
|
|
Action |
Result |
|
|
|
1 |
Add a ContextMenu object |
The new object appears below the form next to the existing |
|
to the form in the |
MainMenu object. |
|
MainForm.cs [Design] |
Note: The Visual Studio window for this step is a bit too |
|
window. |
|
|
big for this space, but is shown in figure 3.9. |
|
|
How-to |
|
|
|
|
|
a. Open the Toolbox win- |
|
|
dow. |
|
|
b. Drag a ContextMenu |
|
|
object onto the form. |
|
|
|
|
2 |
Rename the new context |
The new name is displayed both below the form and in the |
|
menu to ctxtMenuView. |
Properties window. |
|
How-to |
All instances of the ContextMenu object in the source code |
|
Use the Properties window |
MainForm.cs are renamed as well. |
|
to modify the (Name) |
private System.Windows.Forms.ContextMenu |
|
setting for the object. |
|
|
ctxtMenuView; |
|
|
|
|
3 |
Associate this new context |
The down arrow for the ContextMenu property displays the |
|
menu with our |
list of available ContextMenu objects available in the form. In |
|
PictureBox control. |
our case, only the ctxtMenuView is shown. |
|
How-to |
In the InitializeComponent method of our MainForm |
|
a. Display the properties for |
class, the selected context menu is assigned to the property. |
|
the pbxPhoto object. |
private void InitializeComponent() |
|
b. Locate the Context- |
{ |
|
Menu property. |
. . . |
|
pbxPhoto.ContextMenu = this.ctxtMenuView; |
|
|
c. Click to the right of this |
|
|
|
|
|
entry. |
|
|
d. Click the down arrow. |
|
|
e. Select the ctxtMenu- |
|
|
View item from the list. |
|
|
|
|
When you are finished, your Visual Studio .NET window should look something like figure 3.9. Visual Studio generates all the necessary source code for these changes, excerpts of which appear in the steps shown in the previous table.
98 |
CHAPTER 3 MENUS |

Figure 3.9 The component tray below the designer window is used for objects that do not have a representation on the form itself.
The .NET ContextMenu class is essentially a container for the MenuItem objects that appear within the menu. An overview of this class is shown in .NET Table 3.4.
.NET Table 3.4 ContextMenu class
The ContextMenu class is a popup menu that appears at the current cursor location when a user right-clicks an associated object. This class is part of the System.Windows.Forms namespace, and inherits from the Menu class. Context menus are typically associated with a graphical control, and are displayed automatically at a right-click of the mouse within the control. The Control class contains a ContextMenu property inherited by most controls that establishes a context menu to automatically display for the control. See the Menu class description in .NET Table 3.1 on page 72 for a list of inherited members.
|
RightToLeft |
Indicates whether text in the control should be |
|
Public Properties |
|
displayed right to left. |
|
SourceControl |
Gets the last Control object that displayed this |
||
|
|||
|
|
context menu. |
|
|
|
|
|
Public Methods |
Show |
Displays the menu at a specified position within a |
|
|
given control. |
||
|
|
||
|
|
|
|
Public Events |
Popup |
Occurs before a context menu displays its list of |
|
|
child menus. |
||
|
|
||
|
|
|
CONTEXT MENUS |
99 |

3.5.2ADDING MENU ITEMS
We are now ready to add menu items to our context menu. Within Visual Studio, you can click the ctxtMenuView object in the designer window to display a “Type Here” message on your form much like it did for the MainMenu object. You can enter the items to include on this menu and create submenus and handlers as we discussed earlier in the chapter.
We could use this feature to manually enter the contents of the main View menu into our context menu. The behavior and events would have to be set manually for each menu, and the menu would require updating every time the View menu changes. While this could be done, it would be ideal if we could simply copy the contents of the existing View menu into our new context menu, and inherit the behavior and event handlers already established.
Fortunately, the MenuItem class provides a CloneMenu method to create a duplicate copy of a menu item. This permits us to very quickly create our context menu with the identical behavior as the existing View menu in the menu bar.
CLONE THE VIEW MENU ITEMS INTO THE CONTEXT MENU
|
Action |
Result |
|
|
|
1 |
Create a private |
private void DefineContextMenu() |
|
DefineContextMenu |
{ |
|
method at the end of the |
|
|
MainForm.cs source file. |
|
|
|
|
2 |
For each MenuItem in the |
// Copy the View menu into ctxtMenuView |
|
View menu, clone the |
foreach (MenuItem mi in menuView.MenuItems) |
|
menu and add it to our |
{ |
|
ctxtMenuView.MenuItems.Add |
|
|
context menu. |
|
|
(mi.Index, mi.CloneMenu()); |
|
|
|
} |
|
|
} |
|
|
|
3 |
Call the new |
public MainForm() |
|
DefineContextMenu |
{ |
|
. . . |
|
|
method from the end of |
|
|
DefineContextMenu(); |
|
|
the MainForm constructor. |
|
|
} |
|
|
|
Note: Unlike C++, C# does not require forward declara- |
|
|
tions of functions. The method may be used at the begin- |
|
|
ning of the file even though it is not defined until the end |
|
|
of the file. |
|
|
|
In the implementation of DefineContextMenu, note how a foreach to iterate over the items in the View menu. Each item is added to the
View context menu using the MenuItems property of the class. The identical menu index is used for the new menu so that the order of menus in the context menu will match the order used in the View menu. This feature is important, since the foreach loop does not provide any guarantees on the order in which MenuItem objects are presented to the loop.
100 |
CHAPTER 3 MENUS |