- •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
tcImages.Dock = DockStyle.Fill;
tcImages.HotTrack = true;
tcImages.ShowToolTips = true;
For the Form itself, a standard resizable window is used. The tcImages tab control is displayed on the form, and the base name of the album is assigned to the title bar. You can change this form into a more standard modal dialog box if you prefer, using the settings discussed in chapter 8. In our current code, only the ShowInTaskBar and Size properties are assigned.
imagesDlg.Controls.Add(tcImages);
imagesDlg.ShowInTaskbar = false;
imagesDlg.Size = new Size(400, 300);
imagesDlg.Text = "Images in " + Path.GetFileName(_album.FileName);
We display the form as a modal dialog to force the user to close this window before continuing with the application. Note that a Close button is not provided, so the user must close the form using the title bar, the system menu, or the keyboard shortcut Alt+F4.2 After the ShowDialog method returns, we clean up the system resources assigned to the form by calling the Dispose method.
imagesDlg.ShowDialog();
imagesDlg.Dispose();
The application will run just fine with these changes. Of course, all you will see is a very empty TabControl object. We fill this in with TabPage controls in the next section.
11.2TAB PAGES
Tab pages are the heart and soul of a tab control. They define the tabs displayed to the user and the layout of controls that appear when each page is displayed. An overview of the TabPage class is provided in .NET Table 11.2. As you can see, most of the behavior for tab pages is inherited from the Panel class. Normally, the .NET Framework displays each tab as a simple text string, as specified by the Text property for each page inherited from the Control class. Tabs are owner-drawn tabs if the DrawMode property for the containing tab control is set to OwnerDrawFixed. In this case, the DrawItem event for the TabControl must be handled to draw each tab by hand.
2Of course, the Form object does not actually close in the technical sense of invoking the Close method. Since this is a modal dialog box, the framework only calls the Hide method here to permit additional access to the Form and its members. The word “close” is used here for lack of a better word.
TAB PAGES |
359 |
.NET Table 11.2 TabPage class
The TabPage class represents a Panel object with an associated tab that exists within a TabControl object. It contains the set of controls and the tab for a single sheet, or page, of the tab control. The appearance and location of the tab is controlled by the TabControl class, as discussed in .NET Table 11.1.
This class is part of the System.Windows.Forms namespace, and inherits from the Panel class. An overview of the Panel class is provided in .NET Table 7.5 on page 218.
Public
Properties
ImageIndex |
Gets or sets an index into the ImageList associated with |
|
the TabControl object for this page. The corresponding |
|
image is displayed on this page’s tab. |
ToolTipText |
Gets or sets a string to display as the tool tip for this tab. |
|
|
In our application, we will use normal textual tabs that are drawn by the framework. This section creates tab pages by hand and using Visual Studio .NET. First, we will finish the code started in the previous section to display the images associated with an album.
11.2.1CREATING TAB PAGES DYNAMICALLY
Time for us to finish the menuImages_Click handler begun in section 11.1.2. This handler responds to the Click event for the Images menu associated with our List-
Box control in the MyAlbumEditor application. We will create a TabPage control for each image in the album.
Set the version number of the MyAlbumEditor application to 11.2.
CREATE THE TAB PAGES FOR THE IMAGESDLG FORM
|
Action |
Result |
|
|
|
1 |
Display the MainForm.cs file and |
private void menuImages_Click |
|
locate the menuImages_Click |
(object sender, System.EventArgs e) |
|
event handler. |
{ |
|
|
|
2 |
Insert a foreach loop to iterate |
Form imagesDlg = new Form(); |
|
over the photographs in the |
TabControl tcImages = new TabControl(); |
|
album. |
. . . |
|
|
|
|
|
// Create a tab page for each photo |
|
|
foreach (Photograph photo in _album) |
|
|
{ |
|
|
|
3 |
In the loop, create a TabPage |
string shortFileName |
|
object for the photo. |
= Path.GetFileName(photo.FileName); |
|
|
TabPage newPage |
|
|
= new TabPage(shortFileName); |
|
|
newPage.SuspendLayout(); |
|
|
|
360 |
CHAPTER 11 MORE CONTROLS |
CREATE THE TAB PAGES FOR THE IMAGESDLG FORM (continued)
|
|
Action |
Result |
||
|
|
|
|
|
|
4 |
Create a PictureBox control |
PictureBox pbox = new PictureBox(); |
|||
|
containing the image for this |
pbox.BorderStyle = System.Windows. |
|||
|
photo. |
|
|
Forms.BorderStyle.Fixed3D; |
|
|
|
|
pbox.Dock = DockStyle.Fill; |
||
|
|
|
|
|
|
|
|
Settings |
pbox.Image = photo.Image; |
||
|
|
pbox.SizeMode |
|||
|
|
|
|
|
|
|
|
Property |
Value |
= PictureBoxSizeMode.StretchImage; |
|
|
|
BorderStyle |
Fixed3D |
|
|
|
|
Dock |
Fill |
|
|
|
|
SizeMode |
StretchImage |
|
|
|
|
|
|
|
|
5 |
Add the picture box to the page. |
newPage.Controls.Add(pbox); |
|||
|
|
|
|
|
|
6 |
Set the ToolTipText property |
newPage.ToolTipText = photo.FileName; |
|||
|
for the page to the full file name |
|
|||
|
of the photo. |
|
|
|
|
|
|
|
|
|
|
7 |
Add the new tab page to the tab |
tcImages.TabPages.Add(newPage); |
|||
|
control. |
|
|
newPage.ResumeLayout(); |
|
|
|
|
|
|
} |
|
|
|
|
|
. . . |
|
|
|
|
|
imagesDlg.ShowDialog(); |
|
|
|
|
|
imagesDlg.Dispose(); |
|
|
|
|
|
} |
|
|
|
|
|
|
This code will now create the required tab pages for each image, resulting in the dialog shown previously in figure 11.2. The complete implementation of the menuImages_Click handler is shown in the subsequent code. Since the individual lines were discussed in the previous tables, additional commentary is not provided. The annotated set of lines in this code is referenced in the TRY IT! text following the code.
private void menuImages_Click(object sender, System.EventArgs e)
{
Form imagesDlg = new Form();
TabControl tcImages = new TabControl();
imagesDlg.SuspendLayout();
tcImages.SuspendLayout();
// Create a tab page for each photo foreach (Photograph photo in _album)
{
Display the image on
the page b
string shortFileName = Path.GetFileName(photo.FileName); TabPage newPage = new TabPage(shortFileName);
newPage.SuspendLayout();
// Create the PictureBox for this photo PictureBox pbox = new PictureBox();
pbox.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; pbox.Dock = DockStyle.Fill;
TAB PAGES |
361 |
pbox.Image = photo.Image;
pbox.SizeMode = PictureBoxSizeMode.StretchImage;
newPage.Controls.Add(pbox); newPage.ToolTipText = photo.FileName;
tcImages.TabPages.Add(newPage);
newPage.ResumeLayout();
}
//Initialize the tab control tcImages.Dock = DockStyle.Fill; tcImages.HotTrack = true; tcImages.ShowToolTips = true;
//Initialize the form imagesDlg.Controls.Add(tcImages); imagesDlg.ShowInTaskbar = false; imagesDlg.Size = new Size(400, 300);
imagesDlg.Text = “Images in “ + Path.GetFileName(_album.FileName);
tcImages.ResumeLayout();
imagesDlg.ResumeLayout();
// Display the dialog as modal and ignore any result imagesDlg.ShowDialog();
imagesDlg.Dispose();
}
Compile and run your program to see this new dialog. This dialog is resizable, and the controls automatically resize with the window since we set the Dock property to Fill for our controls.
TRY IT! |
The TabControl here is created with the default behavior. You can |
|
change the location and style for the tabs by altering the Alignment and |
|
Appearance properties. Try setting these properties to alternate values |
|
to see how the control then appears. Also set the Multiline property to |
|
true and resize the form to see how multiple rows of tabs are displayed. |
|
For a more complicated change, you will note that each image is dis- |
|
played in a PictureBox control much like an image was displayed way |
|
back in chapter 2. This, of course, has the problem that the image is |
|
stretched and distorted as the window is resized. Fix this by replacing the |
|
use of the PictureBox control in the prior code block with a Paint event |
|
handler for the TabPage object. This code is annotated as b in the prior |
|
code block with “Display the image on the page.” As part of this change, |
|
assign the photo to the Tag property of the newPage object so you can re- |
|
trieve this photo in the Paint handler. The replaced code should look |
|
something like the following: |
|
// Assign a Paint event handler to draw this photo |
|
newPage.Tag = photo; |
|
newPage.Paint += new System.EventHandler(this.newPage_Paint); |
362 |
CHAPTER 11 MORE CONTROLS |
Implement the newPage_Paint event handler to retrieve the Photograph stored in the sender’s Tag parameter and paint the image with the proper aspect ratio. This should be similar to how we painted the image within the Panel for the ScaleToFit display option in chapter 7.
This example is a good reminder that Visual Studio .NET is not needed to create Windows Forms applications. Visual Studio provides a number of nice features that are useful for handling layout and complexity issues, as we have seen. Still, it is good to remember that Visual Studio is just a tool and not a required part of the C# language or the .NET Framework.
That said, managing a number of controls on multiple tab pages would get rather confusing without Visual Studio available. We will see how to use Visual Studio to create tab controls and pages next.
11.2.2CREATING TAB PAGES IN VISUAL STUDIO
In this section we will replace the existing Photographs group box in the MyAlbumEditor application with a tab control. This control will contain the controls currently in the Photographs group box. Here we will only create a single tab page. A second tab page will be added later in the chapter. Figure 11.4 shows how this new window will look.
Figure 11.4
The Photos tab will contain the controls we created in chapter 10. The tab, shown here on the left, can be placed on any side of the tab control.
As you can see, the ListBox and four Button controls have been moved inside a Photos tab page. To make this change, we need to delete the GroupBox control. If we delete the group box directly, we will also delete the contained controls. While we could delete the GroupBox, add the TabControl and a TabPage, and then recreate the controls inside, it would be much nicer if we could somehow move the controls into a tab page directly. This is, in fact, what we will do.
TAB PAGES |
363 |