- •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
|
|
IMPLEMENT PREVIOUS HANDLER |
|
|
|
|
|
|
Action |
|
Result |
|
|
|
|
1 |
Add a Click handler for |
|
protected void menuPrevious_Click |
|
the Previous menu item. |
|
(object sender, System.EventArgs e) |
|
|
|
{ |
|
|
|
|
2 |
Implement this handler |
|
if (_album.CurrentPrev()) |
|
using the CurrentPrev |
|
{ |
|
method. |
|
this.Invalidate(); |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
Compile and run the application to verify that your code produces the screen shown in figure 6.2 earlier in this section.
TRY IT! It would be useful to have First and Last menu items here. These would display the first or last photo in the album, respectively. Add these two menus to the View menu and provide a Click event handler for each menu.
6.5FILES AND PATHS
Before we implement our save methods, a brief talk on the name of an album is in order. While we may store the album in a file such as “C:\Program Files\MyPhotos\sample.abm,” such a name is a bit cumbersome for use in dialogs and on the title bar. The base file name, in this case “sample,” is more appropriate for this purpose. Another issue is where exactly should album files be stored?
This section resolves these issues by defining a default directory where albums are stored and establishing a title bar based on the current album name. These features will then be used to implement a Click event handler for our New menu.
6.5.1CREATING A DEFAULT ALBUM DIRECTORY
While an album file can be placed in any directory, it is nice to provide a common place for such files. This location will be used by default for both opening and saving albums. Common directories for this and other standard information are available from the Environment class, as summarized in .NET Table 6.2.
For our default directory, the GetFolderPath method provides convenient access to the special folders in the system, such as the user’s My Documents directory. There are a number of special folders available, with a few of them listed in .NET Table 6.3. We are interested in the location of the My Documents directory, which corresponds to the Personal enumeration value.
FILES AND PATHS |
175 |
.NET Table 6.2 Environment class
The Environment class represents the current user’s environment, providing the means to retrieve and specify environmental information. This class is sealed and the members defined by this class are static. The Environment class is part of the System namespace.
|
CurrentDirectory |
Gets or sets the fully qualified path of the current |
|
|
directory for this process. |
|
ExitCode |
Gets or sets the exit code for the process. |
|
MachineName |
Gets the NetBIOS name of this local computer. |
|
OSVersion |
Gets an OperatingSystem instance under |
Public Static |
|
which this process is currently running. |
Properties |
TickCount |
Gets the number of milliseconds elapsed since |
|
||
|
|
the system started. |
|
UserName |
Gets the user name that started the current |
|
|
thread for this process. |
|
WorkingSet |
Gets the amount of physical memory mapped to |
|
|
this process context. |
|
|
|
|
Exit |
Terminates this process and returns the |
|
|
specified exit code to the underlying operating |
|
|
system. |
|
GetCommandLineArgs |
Returns an array of string objects containing |
|
|
the command line arguments for the current |
|
|
process. |
|
GetEnvironmentVariable |
Returns the value of a specified environment |
Public Static |
|
variable as a string. |
|
|
|
Methods |
GetEnvironmentVariables |
Returns the set of all environment variables as |
|
||
|
|
an IDictionary instance. |
|
GetFolderPath |
Returns the path of a special folder as identified |
|
|
by the Environment.SpecialFolder |
|
|
enumeration. |
|
GetLogicalDrives |
Returns an array of string objects containing |
|
|
the names of the logical drives on the computer |
|
|
under which this process is running. |
|
|
|
We will use this value to define a static DefaultDir property in our PhotoAlbum class. We will allow a programmer to modify this value, but this provides a starting point for album storage. To distinguish photo albums from other documents, we will create an Albums directory within the My Documents folder.
176 |
CHAPTER 6 COMMON FILE DIALOGS |
.NET Table 6.3 SpecialFolder enumeration
The SpecialFolder enumeration specifies various types of predefined folders in the .NET Framework. This enumeration is used by the GetFolderPath method in the Environment class. This enumeration is defined within the Environment class as part of the System namespace.
|
ApplicationData |
The common directory where application data for the |
|
|
current roaming, or network, user is typically stored. |
|
Cookies |
The directory where Internet cookies are typically stored. |
Enumeration |
Favorites |
The directory where the user’s favorite items are typically |
|
stored. |
|
Values |
Personal |
The directory where the user’s documents are typically |
|
||
|
|
stored. |
|
SendTo |
The directory that contains the Send To menu items. |
|
StartMenu |
The directory that contains the Start menu items. |
|
|
|
Let’s see how this looks by creating the required code.
Set the version number of the MyPhotoAlbum library to 6.5.
CREATE A DEFAULT ALBUM DIRECTORY
|
Action |
Result |
|
|
|
1 |
In the PhotoAlbum.cs file, indicate |
using System.IO; |
|
we are using the system.IO |
|
|
namespace. |
|
|
|
|
2 |
Define static members for the |
static private string _defaultDir = null; |
|
default directory and whether this |
static private bool _initializeDir = true; |
|
directory has been initialized. |
|
|
|
|
3 |
Define a static InitDefaultDir |
static private void InitDefaultDir() |
|
method to initialize the default |
{ |
|
directory setting. |
if (_defaultDir == null) |
|
{ |
|
|
|
|
|
Note: The ampersand ‘@’ in C# |
_defaultDir = Environment.GetFolderPath( |
|
specifies an “as-is” string, where |
Environment.SpecialFolder.Personal); |
|
_defaultDir += @"\Albums"; |
|
|
escape sequences normally |
|
|
} |
|
|
denoted by the backslash charac- |
Directory.CreateDirectory(_defaultDir); |
|
ter are ignored. |
|
|
|
} |
|
|
|
FILES AND PATHS |
177 |
CREATE A DEFAULT ALBUM DIRECTORY (continued)
|
Action |
Result |
|
|
|
4 |
Implement a DefaultDir |
static public string DefaultDir |
|
property to retrieve or assign the |
{ |
|
default directory setting. |
get |
|
{ |
|
|
|
|
|
How-to |
if (_initializeDir) |
|
Use the _initializeDir field to |
{ |
|
InitDefaultDir(); |
|
|
ensure that the directory setting is |
|
|
_initializeDir = false; |
|
|
only initialized once. |
} |
|
|
return _defaultDir; |
|
|
} |
|
|
set |
|
|
{ |
|
|
_defaultDir = value; |
|
|
_initializeDir = true; |
|
|
} |
|
|
} |
|
|
|
The InitDefaultDir method does much of the work for this property. If an explicit value for the default directory has not been set, then this method assigns a value based on the user’s personal directory for documents, with an Albums subdirectory added.
static private void InitDefaultDir()
{
if (_defaultDir == null)
{
_defaultDir == Environment.GetFolderPath( Environment.SpecialFolder.Personal);
_defaultDir += @"\Albums";
}
Since this directory, or any directory provided by the user, may or may not exist at the start of the program, we create the directories as part of our initialization.
Directory.CreateDirectory(_defaultDir);
}
For programmers familiar with earlier development environments from Microsoft, the lack of directory-related classes and dialogs has been a noticeably missing feature. Microsoft has provided a Directory class .NET containing a number of static methods for dealing with directories. This class resides in the System.IO namespace and should simplify the handling of directories in applications. We will not look at this class in detail here. The CreateDirectories method used in our code ensures that each of a string of directories in a given path exist. Note that if the _defaultDir setting is not a well-formed directory string, then the CreateDirectories method will throw an exception.
178 |
CHAPTER 6 COMMON FILE DIALOGS |