- •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
Set the version number of the MyPhotos application to 7.2.
|
|
DELETE THE PICTUREBOX CONTROL |
|
|
|
|
|
|
Action |
|
Result |
|
|
|
|
1 |
Display the MainForm.cs |
|
|
|
[Design] window. |
|
|
|
|
|
|
2 |
Delete the PictureBox |
|
The control no longer appears on the form. |
|
control. |
|
In the MainForm.cs file, the definition for the control (the |
|
|
|
|
|
How-to |
|
pbxPhoto variable) and all references to it in the |
|
Select the Delete item |
|
InitializeComponent method are removed. |
|
from the control’s context |
Note: nonautomated references to this variable must be |
|
|
menu, or simply click on |
|
|
|
|
removed by hand. This will be done during the course of |
|
|
the control and press the |
|
|
|
|
this section. |
|
|
Delete key. |
|
|
|
|
|
|
|
|
|
|
With this task completed, our way is clear to implement the functionality previously provided by the PictureBox control in our MainForm control directly.
7.2.2HANDLING THE IMAGE MENU
One of the unfortunate but necessary side effects of nuking the PictureBox control is that our processing of the Image menu no longer makes sense. We built this with the PictureBoxSizeMode enumeration values in mind. Since we are no longer using this control, we need to change how our menu works.
As an alternative solution, we will create our own enumerator for this purpose to use in place of the PictureBoxSizeMode enumeration. We could provide a long discussion of the individual changes required here, but this is chapter 7 so we’ll just plunge ahead.
In this section we’ll create the new enumeration and begin the process of modifying our menu handlers. The subsequent sections will address issues specific to the child menu items of the Image menu, and complete our implementation of the menu handlers.
|
REPLACE THE MODEMENUARRAY MEMBER |
|
|
|
|
|
Action |
Result |
|
|
|
1 |
In the MainForm.cs file, |
|
|
delete the modeMenuArray |
|
|
and _selectedImageMode |
|
|
fields. |
|
|
|
|
IMAGE DRAWING |
199 |
REPLACE THE MODEMENUARRAY MEMBER (continued)
|
Action |
Result |
|
|
|
2 |
Create a private |
/// <summary> |
|
DisplayMode enumerator |
/// Mode settings for the View->Image |
|
in the MainForm class. |
/// submenu. The order and values here |
|
/// must correspond to the index of |
|
|
|
|
|
|
/// menus in the Image submenu. |
|
|
/// </summary> |
|
|
private enum DisplayMode |
|
|
{ |
|
|
StretchToFit = 0, |
|
|
ActualSize = 1 |
|
|
} |
|
|
|
3 |
Create a private instance of |
private DisplayMode _selectedMode |
|
this enumerator called |
= DisplayMode.StretchToFit; |
|
_selectedMode. |
|
|
|
|
4 |
Replace the use of the old |
private void statusBar1_DrawItem |
|
_selectedImageMode |
(object sender, System.Windows.Forms. |
|
StatusBarDrawItemEventArgs sbdevent) |
|
|
with the appropriate use of |
|
|
{ |
|
|
_selectedMode in the |
|
|
if (sbdevent.Panel == sbpnlImagePercent) |
|
|
statusBar1_DrawItem |
{ |
|
method. |
// Calculate percent of image shown |
|
|
int percent = 100; |
|
|
if (_selectedMode == DisplayMode.ActualSize) |
|
|
{ |
|
|
Photograph photo |
|
|
= _album.CurrentPhoto; |
|
|
Rectangle dr = this.ClientRectangle; |
|
|
int imgWidth = photo.Image.Width; |
|
|
int imgHeight = photo.Image.Height; |
|
|
percent = 100 |
|
|
* Math.Min(dr.Width, imgWidth) |
|
|
* Math.Min(dr.Height, imgHeight) |
|
|
/ (imgWidth * imgHeight); |
|
|
} |
|
|
. . . |
|
|
} |
|
|
} |
|
|
|
5 |
Replace all other instances |
The instances of this variable in menuImage_Popup, |
|
of the old |
menuImage_ChildClick, and OnPaint are replaced. |
|
_selectedImageMode |
Note: Some tweaking of this code is required to make it |
|
with the new |
|
|
work properly. The changes are shown in the subsequent |
|
|
_selectedMode. |
|
|
text and will evolve throughout this section. |
|
|
|
|
|
|
|
Let’s look at the menu handlers here to see how our new DisplayMode enumeration is used. The Popup event handler is called whenever the Image submenu is about to display, while the Click handler is called whenever an Image submenu is selected.
protected void menuImage_Popup (object sender, System.EventArgs e)
{
if (sender is MenuItem)
{
bool bImageLoaded = ( _album.Count > 0 );
MenuItem miParent = (MenuItem)sender;
200 |
CHAPTER 7 DRAWING AND SCROLLING |
foreach (MenuItem mi in miParent.MenuItems)
{
mi.Enabled = bImageLoaded;
mi.Checked = (this._selectedMode == (DisplayMode)mi.Index);
}
}
Cast integer to b enumerated type
}
protected void menuImage_ChildClick (object sender, System.EventArgs e)
{
if (sender is MenuItem)
{
MenuItem mi = |
(MenuItem)sender; |
Cast integer to |
|
|
|
|
|
_selectedMode |
= (DisplayMode) mi.Index; |
b enumerated type |
|
switch (_selectedMode) |
c |
|
|
{ |
|
Handle enumeration |
default:
case DisplayMode.StretchToFit:
// Stretch image to fit the display area. this.Invalidate();
break;
case DisplayMode.ActualSize:
// Display image at actual size. this.Invalidate();
break;
}
statusBar1.Invalidate();
}
This code raises some interesting points about the use of enumerated types.
bThis line simply casts an integer value to an enumerated type. With the extensive error and type checking built into C#, you might think it would be an error to cast an integer to an enumeration value that does not exist. In fact, a standard C# enumeration by definition can hold any integer value, so any integer value can be cast to any enumeration type.
cThis line uses a switch statement to perform the appropriate action based on the current display mode setting. Notice how the StretchToFit case is used as the default setting.
dSince our image will now be drawn directly on the form, we need to call the Form.Invalidate method to force the application to redraw the window using the new setting.
Of course, the menuImage_ChildClick method is not finished yet. We will fill this method in as we enable the corresponding display modes.
IMAGE DRAWING |
201 |
Before we do, one other feature is missing. Our wonderful context menu disappeared along with the PictureBox control. The menu is still around, of course, and is still initialized by the DefineContextMenu method to contain a copy of the View menu. The menu is just not hooked up to any controls at the moment, so it never appears.
We can fix this by attaching this menu to our Form class. Continuing our previous steps:
|
ASSOCIATE THE CONTEXT MENU WITH THE FORM |
|
|
|
|
|
Action |
Result |
|
|
|
7 |
Display the properties for |
|
|
the MainForm object in the |
|
|
MainForm.cs [Design] |
|
|
window. |
|
|
|
|
8 |
Set the ContextMenu |
The property is set in the InitializeComponent method of |
|
property to the |
the MainForm.cs source file. |
|
ctxtMenuView menu. |
this.ContextMenu = ctxtMenuView; |
|
|
|
|
How-to |
|
|
Click the down arrow next |
|
|
to the ContextMenu |
|
|
property to display the |
|
|
available menus. |
|
|
|
|
Our context menu is now associated with the top-level form, and will appear whenever the user right-clicks anywhere in the window.
Your program may or may not compile here, depending on what you did to the OnPaint method when the _selectedImageMode field was removed. We’ll cover this as part of the next section.
7.2.3IMPLEMENTING THE STRETCH TO FIT OPTION
The modification of our Image menu handlers fully eradicates the PictureBox control from our application. While the PictureBox control created some problems, it also drew the current photograph for us. Now we will need to do this by hand, the result of which is shown in figure 7.2. You will note in this figure that the application is lacking the border previously shown around the image by the PictureBox control. This will be addressed later in the chapter.
202 |
CHAPTER 7 DRAWING AND SCROLLING |