- •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
5.2.4CREATING THE PHOTOGRAPH CLASS
The Photograph class represents a photograph stored in a file. Earlier, we laid out this class as follows.
public class Photograph
{
//Create a new instance from a file name.
//Properties:
//- get the file name for the Photograph
//- get the Bitmap for the Photograph
//Methods:
//- see if two Photographs are equal
}
While we could implement this class within the PhotoAlbum.cs file, it makes more sense to separate these two classes into two separate files. In this section we create this new class file and add some initial properties for the class. The following steps create our Photograph.cs source file.
|
|
ADD A PHOTOGRAPH CLASS FILE |
|
|
|
|
|
|
Action |
|
Result |
|
|
|
|
1 |
Open the dialog to add a |
|
The Add New Item dialog opens with the Class template |
|
new class for the |
|
selected. |
|
MyPhotoAlbum project. |
|
|
|
How-to |
|
|
|
a. In Solution Explorer, click |
|
|
|
the MyPhotoAlbum |
|
|
|
project. |
|
|
|
b. Open the Project menu. |
|
|
|
c. Select Add Class…. |
|
|
|
Alternately |
|
|
|
Right-click on the |
|
|
|
MyPhotoAlbum project and |
|
|
|
select Add Class… from |
|
|
|
the Add submenu. |
|
|
|
|
|
|
2 |
Create the new |
|
A Photograph.cs file is added to the MyPhotoAlbum project, |
|
“Photograph.cs” file. |
|
and the default code displays in the main window. |
|
How-to |
|
|
|
Enter the appropriate name |
|
|
|
and click the Open button. |
|
|
|
|
|
|
CLASS LIBRARIES |
141 |
|
|
ADD A PHOTOGRAPH CLASS FILE (continued) |
|
|
|
|
|
|
Action |
|
Result |
|
|
|
|
3 |
Add some class |
|
. . . |
|
documentation. |
|
/// <summary> |
|
|
|
/// The Photograph class represents a single |
|
|
|
/// photo and its properties. |
|
|
|
/// </summary> |
|
|
|
public class Photograph |
|
|
|
. . . |
|
|
|
|
Once again, let’s modify the namespace to be Manning.MyPhotoAlbum.
|
|
MODIFY THE NAMESPACE |
|
|
|
|
Action |
Result |
|
|
|
4 |
Modify the namespace to be |
. . . |
|
Manning.MyPhotoAlbum. |
namespace Manning |
|
|
{ |
|
|
namespace MyPhotoAlbum |
|
|
{ |
|
|
. . . |
|
|
} |
|
|
} |
|
|
|
We now have a fully functional class as part of our library. Of course, it doesn’t do anything yet. Let’s start by tracking the file name and bitmap for the photograph.
DEFINE THE FILE AND BITMAP PROPERTIES
|
Action |
Result |
|
|
|
5 |
Create private member |
public class Photograph |
|
variables to track the file |
{ |
|
name and any Bitmap |
private string _fileName; |
|
private Bitmap _bitmap; |
|
|
object. |
|
|
Note: Here and elsewhere in the book, we indicate that a |
|
|
|
|
|
|
variable is private and not available outside of the con- |
|
|
taining class by prefixing it with an underscore. |
|
|
|
6 |
Create a constructor to |
public Photograph(string fileName) |
|
initialize these members |
{ |
|
from a given file name. |
_fileName = fileName; |
|
_bitmap = null; |
|
|
|
|
|
|
} |
|
|
Note: We allow a Photograph to be created with an |
|
|
invalid file name. |
|
|
|
7 |
Create a FileName |
public string FileName |
|
property to return the |
{ |
|
current file name. |
get { return _fileName; } |
|
} |
|
|
|
|
|
|
|
142 |
CHAPTER 5 REUSABLE LIBRARIES |
DEFINE THE FILE AND BITMAP PROPERTIES (continued)
|
Action |
Result |
|
|
|
8 |
Create an Image property |
public Bitmap Image |
|
to return the corresponding |
{ |
|
Bitmap object. |
get |
|
{ |
|
|
|
|
|
Note: We intentionally |
if (_bitmap == null) |
|
ignore any error here. We |
{ |
|
_bitmap = new Bitmap(_fileName); |
|
|
will fix this later in the |
|
|
} |
|
|
chapter. |
return _bitmap; |
|
|
} |
|
|
} |
|
|
|
This is the first time we’ve created our own properties, so it is worth a short discussion. A property in C# is created much like a method. You define an access level, a type, and a name for the property. By convention, property and method names begin with a capital letter. The lack of parentheses after the name informs the compiler that this is a property and not a method.
Inside the braces, the access methods for the property are defined. The access methods provide read access, via the get keyword, or write access, via the set keyword. The get access method must return the defined type, while the set access method uses the reserved word value to access the value provided on the right side of the equals sign ‘=’. For example, if we wanted users of our Photograph class to set the FileName property, we could code this as follows:
public string FileName
{
get { return _fileName; }
set { _fileName = value; } // example only, not in our code
}
Of course, in an actual implementation it might be good to verify that the value provided to the set call is a real file and does indeed represent a photograph. For our purposes, the Photograph class is tied to a specific file name, so we do not provide a set implementation here. In this case the FileName property is said to be read-only, since the value can be read but not written.
Practically, properties permit safe access to a class without the need to expose internal variables or other features. To duplicate the get and set functionality for a file name member in C++, programmers typically provide methods such as
Name and GetFileName for this purpose. Properties formalize this concept for C# so that all programs use a standard mechanism for this style access.
Since properties are invoked similar to methods, additional calculations can be performed as part of their definition. In the code for the Image property, for example, the Bitmap is created as required before returning it to the user.
public Bitmap Image
{
get
CLASS LIBRARIES |
143 |
{
if (_bitmap == null)
{
_bitmap = new Bitmap(_fileName);
}
return _bitmap;
}
}
Astute readers will note here that the given file may or may not exist and may or may not be an actual image file. We will handle any exception that occurs as a result of such an error in a moment.
We now have enough to link our classes into the main application. One problem remains: the MyPhotoAlbum project will once again not compile. Now the error is something like this:
Error The type or namespace name 'Bitmap' could not be found (are
you missing a using directive or an assembly reference?)
This is because Bitmap is part of the System.Drawing namespace, which is referenced by our MyPhotos project, but not the MyPhotoAlbum project. Unlike System.Collections, this namespace is provided in a separate library, namely the System.Drawing.dll library. We need to reference this DLL and then use it in our class.
ADD SYSTEM.DRAWING REFERENCE
|
Action |
Result |
|
|
|
9 |
Display the Add Reference |
|
|
dialog for the |
|
|
MyPhotoAlbum project. |
|
|
|
|
10 |
Add System.Drawing.dll as |
The System.Drawing assembly appears in the References list |
|
a reference. |
for the MyPhotoAlbum project. |
|
How-to |
|
|
a. Click the .NET tab. |
|
|
b. Locate and click the Sys- |
|
|
tem.Drawing.dll item |
|
|
from the list. |
|
|
c. Click the Select button. |
|
|
d. Click the OK button. |
|
|
|
|
11 |
Add a using directive for |
The Photograph.cs file now contains two using directives: |
|
the System.Drawing |
using System; |
|
namespace at the top of |
|
|
using System.Drawing; |
|
|
the file. |
|
|
|
|
144 |
CHAPTER 5 REUSABLE LIBRARIES |