
- •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

.NET Table 15.5 NodeLabelEditEventArgs class
The NodeLabelEditEventArgs class represents the event data associated with the BeforeLabelEdit and AfterLabelEdit events in the TreeView class. This class is part of the
System.Windows.Forms namespace, and inherits from the System.EventArgs class.
|
CancelEdit |
Gets or sets whether the edit operation should |
|
|
be cancelled. This property can be set both |
|
|
before and after the node is edited. |
Public Properties |
Label |
Gets the new text to assign to the label of the |
|
||
|
|
indicated node. |
|
Node |
Gets the TreeNode object being edited. |
|
|
|
In our application, we will permit nodes to be edited using the menuEditLabel menu item, or by pressing the F2 key when a tree node is selected and the tree view has the focus. The following table details the steps required for this change:
SUPPORT EDITING OF TREE NODE LABELS
|
Action |
Result |
|
|
|
1 |
Set the LabelEdit property for |
Tree node labels may now be edited. |
|
the TreeView control to true |
|
|
in the MainForm.cs [Design] |
|
|
window. |
|
|
|
|
2 |
Handle the KeyDown event for |
private void treeViewMain_KeyDown |
|
the TreeView control to initiate |
(object sender, System.Windows. |
|
a label edit when the F2 key is |
Forms.KeyEventArgs e) |
|
{ |
|
|
pressed in the tree control. |
|
|
if (e.KeyCode == Keys.F2) |
|
|
|
{ |
|
|
if (treeViewMain.SelectedNode != null) |
|
|
{ |
|
|
treeViewMain.SelectedNode.BeginEdit(); |
|
|
e.Handled = true; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
3 |
Update the menuEdit_Popup |
private void menuEdit_Popup |
|
event handler to use the text |
(object sender, System.EventArgs e) |
|
“Node” for the |
{ |
|
if (treeViewMain.Focused) |
|
|
menuEditLabel menu when |
|
|
{ |
|
|
the TreeView has the focus. |
menuEditLabel.Enabled |
|
How-to |
= (treeViewMain.SelectedNode != null); |
|
menuEditLabel.Text = "&Node"; |
|
|
Use the Focused property for |
} |
|
the TreeView class. |
else // assume ListView has focus |
|
|
{ |
|
|
menuEditLabel.Enabled |
|
|
= (listViewMain.SelectedItems.Count > 0); |
|
|
if (this._albumsShown) |
|
|
menuEditLabel.Text = "&Name"; |
|
|
else |
|
|
menuEditLabel.Text = "&Caption"; |
|
|
} |
|
|
} |
|
|
|
FUN WITH TREE VIEWS |
517 |

SUPPORT EDITING OF TREE NODE LABELS (continued)
|
Action |
Result |
|
|
|
4 |
Update the menuEdit- |
private void menuEditLabel_Click |
|
Label_Click event handler to |
(object sender, System.EventArgs e) |
|
edit the appropriate item based |
{ |
|
if (treeViewMain.Focused) |
|
|
on the current focus. |
|
|
{ |
|
|
|
if (treeViewMain.SelectedNode != null) |
|
|
treeViewMain.SelectedNode.BeginEdit(); |
|
|
} |
|
|
else if (listViewMain.SelectedItems.Count > 0) |
|
|
listViewMain.SelectedItems[0].BeginEdit(); |
|
|
} |
|
|
|
5 |
Handle the AfterLabelEdit |
private void treeViewMain_AfterLabelEdit |
|
event for the TreeView control. |
(object sender, System.Windows. |
|
|
Forms.NodeLabelEditEventArgs e) |
|
How-to |
{ |
|
a. Cancel the edit if the new |
if (e.Label == null) |
|
{ |
|
|
text is null. |
|
|
// Edit cancelled by the user |
|
|
b. Do nothing if the node is a |
e.CancelEdit = true; |
|
root node. |
return; |
|
} |
|
|
c. For an album node, use the |
|
|
|
|
|
UpdateAlbumName.method. |
// No changes required for root node |
|
d. For a photograph node, use |
if (e.Node.Parent == null) |
|
return; |
|
|
the UpdatePhotoCaption |
|
|
method. |
string fileName = e.Node.Tag as string; |
|
|
if (Path.GetExtension(fileName) == ".abm") |
|
Note: We permit the user to |
e.CancelEdit = !UpdateAlbumName(e.Label, |
|
e.Node); |
|
|
edit the root node here to alter |
|
|
else |
|
|
a top-level name in the tree, |
|
|
e.CancelEdit = !UpdatePhotoCaption(e.Label, |
|
|
even though this change is dis- |
e.Node); |
|
carded when the application |
} |
|
|
|
|
exits. A more robust solution |
|
|
might be to prevent this from |
|
|
occurring, or to save the |
|
|
change in a configuration file. |
|
|
|
|
6 |
Rewrite the UpdateAlbum- |
private bool UpdateAlbumName |
|
Name method to accommodate |
(string newName, object obj) |
|
both list items and tree nodes. |
{ |
|
ListViewItem item = obj as ListViewItem; |
|
|
|
|
|
How-to |
TreeNode node = obj as TreeNode; |
|
|
|
|
a. Change the second parame- |
// Determine the file name |
|
ter to an object rather than |
string fileName = null; |
|
a ListViewItem. |
if (item != null) |
|
b. Convert the given object to |
{ |
|
fileName = item.Tag as string; |
|
|
both a list item and a tree |
node = FindNode(fileName, false); |
|
node. |
} |
|
c. Determine the file name for |
else if (node != null) |
|
fileName = node.Tag as string; |
|
|
the appropriate object. |
Note: Recall that the list view’s AfterLabelEdit |
|
d. If the object is a list view |
|
|
event handler from chapter 14 provides a ListView- |
|
|
item, also find the node cor- |
|
|
Item object when calling this method. This invocation |
|
|
responding to this item. |
|
|
is still valid and is properly dealt with by this code. |
|
|
|
|
|
|
|
518 |
CHAPTER 15 TREE VIEWS |

SUPPORT EDITING OF TREE NODE LABELS (continued)
|
Action |
Result |
|
|
|
7 |
Rename the file. |
// Rename the file |
|
How-to |
string newFileName = null; |
|
if (fileName != null) |
|
|
Use the RenameFile method |
{ |
|
from chapter 14. |
newFileName |
|
|
= RenameFile(fileName, newName, ".abm"); |
|
|
} |
|
|
if (newFileName == null) |
|
|
{ |
|
|
MessageBox.Show("Unable to rename album " |
|
|
+ "to this name."); |
|
|
return false; |
|
|
} |
|
|
|
8 |
Update the Tag property for the |
// Update the appropriate Tag property |
|
appropriate object. |
if (item != null) |
|
Note: When the object is a list |
{ |
|
item.Tag = newFileName; |
|
|
item, this updates the corre- |
if (node != null) |
|
sponding node as well. |
node.Text = newName; |
|
} |
|
|
|
|
|
|
else if (node != null) |
|
|
node.Tag = newFileName; |
|
|
return true; |
|
|
} |
|
|
|
9 |
Rewrite the UpdatePhoto- |
private bool UpdatePhotoCaption |
|
Caption method to accom- |
(string caption, object obj) |
|
modate both list items and tree |
{ |
|
ListViewItem item = obj as ListViewItem; |
|
|
nodes. |
|
|
TreeNode node = obj as TreeNode; |
|
|
How-to |
// Determine the album index |
|
a. Change the second param- |
|
|
int index = -1; |
|
|
eter to an object rather |
if ((item != null) && (item.Tag is int)) |
|
than a ListViewItem. |
{ |
|
index = (int)item.Tag; |
|
|
b. Convert the given object |
|
|
node = FindNode(_album[index].FileName, |
|
|
to both a list item and a |
false); |
|
tree node. |
} |
|
else if (node != null) |
|
|
c. Determine the album index |
|
|
{ |
|
|
for the appropriate object. |
index = node.Index; |
|
d. If the object is a list view |
} |
|
|
|
|
item, also find the node |
|
|
corresponding to this item. |
|
|
|
|
10 |
Return false if the caption |
if ((caption.Length == 0) || (index < 0)) |
|
cannot be updated. |
{ |
|
|
MessageBox.Show("Invalid caption value."); |
|
|
return false; |
|
|
} |
|
|
|
FUN WITH TREE VIEWS |
519 |

SUPPORT EDITING OF TREE NODE LABELS (continued)
|
Action |
Result |
|
|
|
11 |
Update the photograph’s |
// Update caption |
|
caption, and save the changes |
_album[index].Caption = caption; |
|
to the album. |
if (item != null && node != null) |
|
{ |
|
|
|
|
|
Note: When the object is a list |
// Update node text as well |
|
item, this updates the corre- |
node.Text = caption; |
|
} |
|
|
sponding node as well. |
|
|
|
|
|
|
// Save the changes to the album |
|
|
. . . |
|
|
} |
|
|
|
Our program now permits editing of nodes in the TreeView and items in the ListView. Editing is initiated with the menuLabelEdit menu or the F2 key, and is based on which control currently has the focus.
In both update methods, note how the as keyword is used to convert the given object into both a TreeView and a ListView, as is shown in the following excerpt. The remainder of each method executes the appropriate statements based on which type of control is provided.
ListViewItem item = obj as ListViewItem;
TreeNode node = obj as TreeNode;
Also of note is our use of the FindNode method created earlier in the chapter as part of section 15.4.2. As you may recall, we included a parameter to this method that indicated whether to expand the selected node. We set this second parameter to false here to ensure that the contents of the tree view control are not altered.
Our final change is to support the display of our album and photograph property dialogs from the TreeView control.
15.5.3UPDATING THE PROPERTIES MENU
In chapter 14 we created a Properties menu. We handled the Click event for this menu in a menuProperties_Click method, and created the DisplayAlbumProperties and DisplayPhotoProperties methods to display the two types of dialogs
required. Here we would like to change the behavior of this menu to the following:
•When the TreeView has the focus, display the appropriate properties dialog if an album node or a photograph node is selected.
•When the ListView has the focus, display the appropriate properties dialog for the selected item.
•When the PictureBox has the focus, display the photograph properties dialog associated with the displayed image.
To make this change, we will modify our Display methods to accept either a ListViewItem or a TreeNode object. The following table details the changes required.
520 |
CHAPTER 15 TREE VIEWS |