- •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
UPDATE THE MENUALBUMS_CLICK EVENT HANDLER
|
Action |
Result |
|
|
|
1 |
Locate the menuAlbums_Click event |
private void menuAlbums_Click |
|
handler in the MainForm.cs code |
(object sender, System.EventArgs e) |
|
window. |
{ |
|
|
|
|
|
|
2 |
Modify this handler to select the Default |
// Select Default Albums node |
|
Albums tree node. |
if (treeViewMain.Nodes.Count > 0) |
|
How-to |
{ |
|
treeViewMain.SelectedNode |
|
|
Set the SelectedNode property for the |
= treeViewMain.Nodes[0]; |
|
tree to the first node in the tree. |
} |
|
} |
|
|
|
|
|
|
|
Since we initialize the tree with a top-level node, we know this will always exist and appear first in the tree view object’s Nodes collection. We select this by assigning this node to the SelectedNode property of the tree.
For the Photos menu, you may recall that we created a menuView_Popup event handler that enables this menu only if an album is selected in the ListView control. The existing menuPhotos_Click event handler, shown in the following code, already activates the selected item. This behavior works just fine for our current application, so no changes are required to this handler.
private void menuPhotos_Click(object sender, System.EventArgs e)
{
// Activate the selected album listViewMain_ItemActivate(sender, e);
}
The final event handler, the listViewMain_ItemActivate method, requires some discussion. Our existing handler, shown in the following code, only permits albums to be activated. This handler retrieves the selected item, opens the album file corresponding to the item, and calls LoadPhotoData to display the photographs in the album.
private void listViewMain_ItemActivate(object sender, EventArgs e)
{
if (_albumsShown && listViewMain.SelectedItems.Count > 0)
{
ListViewItem item = listViewMain.SelectedItems[0]; string fileName = item.Tag as string;
// Open the album for this item PhotoAlbum album = null;
if (fileName != null)
album = OpenAlbum(fileName); if (album == null)
{
MessageBox.Show(
"The photographs for this album cannot be displayed.");
510 |
CHAPTER 15 TREE VIEWS |
return;
}
// Switch to a photograph view LoadPhotoData(album);
}
}
In our new code, we will permit any type of item to be activated. Albums will display the photos in the album, and photographs will display a blank list, which we will update shortly to display the actual image. Our logic to select the TreeNode corresponding to the item will go something like this:
private void listViewMain_ItemActivate(object sender, EventArgs e)
{
if (listViewMain.SelectedItems.Count > 0)
{
//Find the file path for the selected item
//Find the tree node with an identical path
//Select the node to activate it
}
}
We will need some assistance with the first two steps. As you may recall, we utilized the Tag property in chapter 14 to store the file name of album items and the index of photograph items. We can use this property to retrieve the path for either type item.
Our next step is to locate the node which matches a given file path. This is a little trickier than it seems, since the node may not yet exist. There are two critical observations we can make in order to properly implement this functionality:
•First, the node corresponding to the parent of the activated item will already be selected in the tree. We ensure that a node is selected at all times in our tree, so we can count on this fact to identify the Nodes collection containing our desired node.
•Second, the matching node may not actually exist. For example, if a user activates a photograph, a node for the photograph will only exist if the album node containing the photo has been expanded. As a result, we must expand the parent node before we search for a matching node to ensure that the node exists.
With these facts in mind, we are ready to implement a method to locate a node, which we will call FindNode.
NODE SELECTION |
511 |
|
IMPLEMENT A FINDNODE METHOD |
|
|
|
|
|
Action |
Result |
|
|
|
3 |
Create a new FindNode |
private TreeNode FindNode |
|
method. |
(string fileName, bool expandNode) |
|
Note: This method accepts a |
{ |
|
|
|
|
file name and returns the |
|
|
matching TreeNode object, if |
|
|
any. |
|
|
This also accepts a boolean |
|
|
value indicating whether to |
|
|
expand the node. This feature |
|
|
will come in handy later in the |
|
|
chapter. |
|
|
|
|
4 |
Make sure the selected node is |
TreeNode node = treeViewMain.SelectedNode; |
|
not null. |
if (node == null) |
|
Note: This value should never |
return null; |
|
|
|
|
be null, but it is always good |
|
|
to check. |
|
|
|
|
5 |
If expandNode is true, make |
// Ensure contents of node are available |
|
sure the contents of the |
if (expandNode) |
|
selected node are loaded into |
node.Expand(); |
|
|
|
|
the tree. |
|
|
|
|
6 |
Find the node that matches the |
// Search for a matching node |
|
given string. |
foreach (TreeNode n in node.Nodes) |
|
|
{ |
|
How-to |
string nodePath = n.Tag as string; |
|
a. For each child of the selected |
if (nodePath == fileName) |
|
{ |
|
|
node, find the file associated |
|
|
// Found it! |
|
|
with the node. |
return n; |
|
b. If a match is found, return it to |
} |
|
|
|
|
the caller. |
|
|
|
|
7 |
If no match is found, return |
} |
|
null. |
return null; |
|
|
|
|
|
} |
|
|
|
With these changes in place, we can revamp our ItemActivate handler to select the corresponding tree node.
REIMPLEMENT THE ITEMACTIVATE EVENT HANDLER
|
Action |
Result |
|
|
|
8 |
Replace the ItemActivate event |
private void listViewMain_ItemActivate |
|
handler in the MainForm.cs code |
(object sender, System.EventArgs e) |
|
window. |
{ |
|
|
|
|
|
|
512 |
CHAPTER 15 TREE VIEWS |