- •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 PROPERTIES MENU TO HANDLE TREE NODES
|
Action |
|
Result |
|
|
|
|
1 |
In the MainForm.cs code |
private void menuProperties_Click |
|
|
window, update the |
(object sender, System.EventArgs e) |
|
|
menuProperties_Click event |
{ |
|
|
if (treeViewMain.Focused) |
||
|
handler to accommodate the |
||
|
{ |
|
|
|
three controls that might have |
TreeNode node = treeViewMain.SelectedNode; |
|
|
the focus. |
string file = node.Tag as string; |
|
|
|
if (node == null || node.Parent == null |
|
|
How-to |
|| file == null) |
|
|
a. For the TreeView control, |
return; |
// do nothing |
|
|
|
|
|
ignore the parent node and |
if (Path.GetExtension(file) == ".abm") |
|
|
call the appropriate Proper- |
DisplayAlbumProperties(node); |
|
|
ties method based on the |
else |
|
|
node type. |
DisplayPhotoProperties(node); |
|
|
} |
|
|
|
b. For the PictureBox control, |
|
|
|
else if (pictureBoxMain.Focused) |
||
|
call the DisplayPhoto- |
{ |
|
|
Properties method on the |
// Display photograph for this image |
|
|
TreeNode node = treeViewMain.SelectedNode; |
||
|
selected photo node. |
||
|
if (node != null) |
||
|
c. For the ListView control, |
DisplayPhotoProperties(node); |
|
|
the code is the same as in |
} |
|
|
else |
|
|
|
chapter 14. |
|
|
|
if (listViewMain.SelectedItems.Count > 0) |
||
|
|
{ |
|
|
|
ListViewItem item |
|
|
|
= listViewMain.SelectedItems[0]; |
|
|
|
if (this._albumsShown) |
|
|
|
DisplayAlbumProperties(item); |
|
|
|
else |
|
|
|
DisplayPhotoProperties(item); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
2 |
Rewrite the DisplayAlbum- |
private void DisplayAlbumProperties |
|
|
Properties method to accept |
(object obj) |
|
|
an object instance. |
{ |
|
|
ListViewItem item = obj as ListViewItem; |
||
|
|
||
|
How-to |
TreeNode node = obj as TreeNode; |
|
|
|
|
|
|
a. Convert the given object to |
// Open the album as appropriate |
|
|
a ListViewItem and a |
PhotoAlbum album = null; |
|
|
TreeNode instance. |
if (item != null) |
|
|
b. Open the PhotoAlbum using |
{ |
|
|
string fileName = item.Tag as string; |
||
|
whichever object is not |
if (fileName != null) |
|
|
null. |
album = this.OpenAlbum(fileName); |
|
|
c. If the album could not be |
} |
|
|
else if (node != null) |
||
|
opened, display an error |
{ |
|
|
message. |
album = OpenTreeAlbum(node); |
|
|
|
} |
|
|
|
if (album == null) |
|
|
|
. . . // as in chapter 14 |
|
|
|
|
|
FUN WITH TREE VIEWS |
521 |
UPDATE PROPERTIES MENU TO HANDLE TREE NODES (continued)
|
Action |
Result |
|
|
|
3 |
When displaying the album edit |
using (AlbumEditDlg dlg |
|
dialog, only update the list item |
= new AlbumEditDlg(album)) |
|
settings if the given item is a list |
{ |
|
if (dlg.ShowDialog() == DialogResult.OK) |
|
|
view item. |
|
|
{ |
|
|
Note: If the given item is a tree |
// Save changes made by the user |
|
. . . |
|
|
node, then photographs are dis- |
|
|
// Update item settings |
|
|
played in the list view, and |
if (item != null) |
|
these settings should not be |
{ |
|
updated. |
item.SubItems[MainForm. |
|
AlbumTitleColumn].Text |
|
|
|
|
|
|
= album.Title; |
|
|
bool hasPwd = (album.Password != null) |
|
|
&& (album.Password.Length > 0); |
|
|
item.SubItems[MainForm. |
|
|
AlbumPwdColumn].Text |
|
|
= (hasPwd ? "y" : "n"); |
|
|
} |
|
|
} |
|
|
} |
|
|
album.Dispose(); |
|
|
} |
|
|
|
4 |
Modify the |
private void DisplayPhotoProperties |
|
DisplayPhotoProperties |
(object obj) |
|
{ |
|
|
method to accept an object |
|
|
ListViewItem item = obj as ListViewItem; |
|
|
instance. |
|
|
TreeNode node = obj as TreeNode; |
|
|
How-to |
int index = 0; |
|
This is similar, at least in spirit, to |
|
|
if (item != null && (item.Tag is int)) |
|
|
the DisplayAlbumProperties |
{ |
|
method. |
index = item.Tag; |
|
|
} |
|
|
else if (node != null) |
|
|
{ |
|
|
index = node.Index; |
|
|
} |
|
|
_album.CurrentPosition = index; |
|
|
|
522 |
CHAPTER 15 TREE VIEWS |
UPDATE PROPERTIES MENU TO HANDLE TREE NODES (continued)
|
Action |
Result |
|
|
|
5 |
After displaying the dialog, |
using (PhotoEditDlg dlg |
|
update the list or node with any |
= new PhotoEditDlg(_album)) |
|
modified photograph settings. |
{ |
|
if (dlg.ShowDialog() == DialogResult.OK) |
|
|
|
|
|
Note: Recall that our photo edit |
{ |
|
dialog permits all photographs |
// Save any changes made |
|
. . . |
|
|
in an album to be updated. As a |
|
|
// Update controls with new settings |
|
|
result, when the photographs |
TreeNode baseNode = null; |
|
are shown in the tree node, the |
if (item != null) |
|
label for each related node must |
{ |
|
LoadPhotoData(_album); |
|
|
be updated as well. This is true |
|
|
baseNode = treeViewMain.SelectedNode; |
|
|
regardless of the type object |
} |
|
given. |
else if (node != null) |
|
|
{ |
|
|
baseNode = node.Parent; |
|
|
} |
|
|
if (baseNode != null) |
|
|
{ |
|
|
// Update all child labels |
|
|
foreach (TreeNode n in baseNode.Nodes) |
|
|
{ |
|
|
n.Text = _album[n.Index].Caption; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
As you can see, the display methods use the as keyword to convert a given object into both a ListViewItem and a TreeNode instance. Whichever instance is non- null indicates how to display the property dialog.
TRY IT! As a further change to our TreeView control, add a context menu to this control to perform the following tasks.
1An “Add Directory” menu item that permits a new album directory to be added to the tree. This should prompt for a directory name and add a top-level node to the tree for each album discovered in that directory.
2A “Properties” menu item that displays the properties dialog for the nearest node. This should select the nearby node, and then call the
PerformClick method for the menuProperties menu.
3A “Delete” menu item that deletes a node from the tree. This should
delete the album file from the file system or the Photograph from the containing album for the given node. You should prompt the user to make sure they really wish to do this.
You will need to use the GetNodeAt method to locate the TreeNode instance at a given pixel position, so that the action applies to the specific tree node located at the current mouse position.
FUN WITH TREE VIEWS |
523 |
You could also implement these items within the ListView control as well. This completes our discussion on the TreeView class. Before we move on, let’s do a quick recap of what we covered in this chapter.
15.6RECAP
In this chapter we extended the MyAlbumExplorer project built in chapter 14 to add a TreeView control. We divided our main window using the Splitter class in order to create a classic explorer window such as that used in the Windows operating system for browsing the file system.
A tree view contains a hierarchy of TreeNode objects, and we created a tree displaying our album files and the photos in each album. We discussed common operations within a tree view such as expand, collapse, selection, and label editing. During the course of the chapter, the ListView and TreeView controls were integrated to display a common interface, with changes to one control reflected in the other control. We also added a PictureBox control in order to display the image associated with a selected photograph node in the tree.
The explorer interface we saw in these last two chapters is one of three kinds of standard Windows interfaces. In part 2 of this book we built what is called a single document interface. In the next chapter we will look at another kind of interface, namely the multiple document interface.
524 |
CHAPTER 15 TREE VIEWS |