- •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
Figure 16.8 The title bar for our MDI application must handle the various types of child forms the application can display.
We should also point out that MDI child forms do not receive the Activated or Deactivate events. As a result, when converting from a single document interface into a multiple document interface, any tasks performed in these events must now be handled via another mechanism. Often the MdiChildActivate event can handle the work previously done in these events. Another option is to use the focus-related events, such as the Enter or Leave event. We will look at the activation events in our MainForm window in a moment.
Let’s implement an MdiChildActivate event handler to update the title bar for our application.
UPDATE TITLE BAR IN THE PARENT FORM
|
Action |
Result |
|
|
|
1 |
In the ParentForm.cs code |
protected override void OnMdiChildActivate |
|
window, override the protected |
(System.EventArgs e) |
|
OnMdiChildActivate method. |
{ |
|
|
|
|
|
|
2 |
Implement this method to set |
SetTitleBar(); |
|
the title bar for the MDI |
base.OnMdiChildActivate(e); |
|
application. |
} |
|
|
|
|
|
|
3 |
In the MainForm.cs code |
public string AlbumTitle |
|
window, add an AlbumTitle |
{ |
|
property to retrieve the title of |
get { return _album.Title; } |
|
} |
|
|
the currently displayed album. |
|
|
|
|
|
|
|
554 |
CHAPTER 16 MULTIPLE DOCUMENT INTERFACES |
UPDATE TITLE BAR IN THE PARENT FORM (continued)
|
Action |
Result |
|
|
|
4 |
Back in the ParentForm.cs code |
protected void SetTitleBar() |
|
window, implement the |
{ |
|
SetTitleBar method to |
Version ver |
|
= new Version(Application.ProductVersion); |
|
|
retrieve the version number for |
|
|
|
|
|
the application. |
|
|
|
|
5 |
If the active child is a MainForm |
string titleBar |
|
object, include the album title in |
= "{0} - MyPhotos MDI {1:#}.{2:#}"; |
|
the title bar. |
if (ActiveMdiChild is MainForm) |
|
|
|
|
How-to |
{ |
|
Cast the active child to a |
string albumTitle |
|
= ((MainForm)ActiveMdiChild).AlbumTitle; |
|
|
MainForm object in order to |
|
|
this.Text = String.Format(titleBar, |
|
|
retrieve the current album title. |
albumTitle, ver.Major, ver.Minor); |
|
|
} |
|
|
|
6 |
If the active child is a PixelDlg |
else if (ActiveMdiChild is PixelDlg) |
|
object, display the string “Pixel |
{ |
|
Data” in the title bar. |
this.Text = String.Format(titleBar, |
|
"Pixel Data", ver.Major, ver.Minor); |
|
|
|
|
|
|
} |
|
|
|
7 |
Otherwise, just display the |
else |
|
version number in the title bar. |
{ |
|
|
this.Text = String.Format( |
|
|
"MyPhotos MDI {0:#}.{1:#}", |
|
|
ver.Major, ver.Minor); |
|
|
} |
|
|
} |
|
|
|
8 |
Also set the title bar in the |
protected override void OnLoad(EventArgs e) |
|
OnLoad method. |
{ |
|
Note: This sets the title bar as |
PixelDlg.GlobalMdiParent = this; |
|
SetTitleBar(); |
|
|
the application begins, before |
base.OnLoad(e); |
|
any child windows are dis- |
|
|
} |
|
|
played. |
|
|
|
|
|
|
|
The text to appear in the title bar depends on which type of window is currently active. When no window, or an unrecognized window, is active, then the title bar simply includes the version number. The MdiChildActivate event gives no indication of the activating child, so we use the ActiveMdiChild property to retrieve the active Form. We separate the title bar logic into a separate member SetTitleBar, which allows us to call this method from the OnLoad method as well as our event handler.
Compile and run the application to verify that these changes work as expected. The title bar for both parent and child forms is rather similar. Feel free to modify one or the other to make the title bars more unique. If you do this, make sure you consider the behavior of the MainForm class as both an SDI and MDI application.
MDI CHILDREN |
555 |
16.4.5REVISITING THE ACTIVATION EVENTS
Before we leave this section, there is one more additional change required in our program. Take a look at the following OnActivated and OnDeactivate methods from the MainForm class. As we mentioned previously, these events are not received by MDI child forms, so our existing methods will never be called.
protected override void OnDeactivate(EventArgs e)
{
if (ctrlKeyHeld) ReleaseControlKey();
base.OnDeactivate(e);
}
protected override void OnActivated(EventArgs e)
{
// Update toggle toolbar button if required
if (this._dlgPixel == null || _dlgPixel.IsDisposed) AssignPixelToggle(false);
else AssignPixelToggle(_dlgPixel.Visible);
base.OnActivated(e);
}
As you may recall, we overrode the OnDeactivate method in earlier chapters to note that the Ctrl key should be released when the Form is no longer the active application on the desktop. We overrode the OnActivated method as part of the implementation for a toggle toolbar button tied to the PixelDlg form for the window. The deactivate logic is still required, since the Ctrl key is still a part of our MDI application. The pixel toggle button is not included in our current MDI application, so the activation logic is not required here.
For the Ctrl key logic, we can duplicate the deactivation logic in an OnLeave method. This method, you may recall, is invoked when a control, in this case our form, loses focus. A standalone window, such as our SDI application, does not receive this event, so this addition has no effect on our SDI program.
ENSURE THE CTRL KEY IS RELEASED WHEN AN MDI CHILD FORM LOSES FOCUS
|
Action |
Result |
|
|
|
1 |
In the MainForm.cs code |
protected override void OnLeave(EventArgs e) |
|
window, override the OnLeave |
{ |
|
method to duplicate the logic |
if (IsMdiChild && ctrlKeyHeld) |
|
ReleaseControlKey(); |
|
|
from the OnDeactivate |
|
|
|
|
|
method for the MDI application. |
base.OnLeave(e); |
|
|
} |
|
|
|
556 |
CHAPTER 16 MULTIPLE DOCUMENT INTERFACES |