Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# ПІДРУЧНИКИ / c# / Manning - Windows.forms.programming.with.c#.pdf
Скачиваний:
108
Добавлен:
12.02.2016
Размер:
14.98 Mб
Скачать

Since it is possible to have more than one handler for an event, the += notation is used to add a new event handler without removing any existing handlers. When multiple event handlers are registered, the handlers are typically called sequentially in the same order in which they were added. The System.EventHandler is a delegate in C#, and specifies the format required to process the event. In this case, EventHandler is defined internally by the .NET Framework as

public delegate void EventHandler(object sender, EventArgs e);

A delegate is similar to a function pointer in C or C++ except that delegates are typesafe. The term type-safe means that code is specified in a well-defined manner that can be recognized by a compiler. In this case, it means that an incorrect use of a delegate is a compile-time error. This is quite different than in C++, where an incorrect use of a function pointer may not cause an error until the program is running.

By convention, and to ensure interoperability with other languages, event delegates in .NET accept an object parameter and an event data parameter. The object parameter receives the source, or sender, of the event, while the event data parameter receives any additional information for the event. Typically, the sender parameter receives the control that received the event. In our case, this is the actual Button instance. The e parameter receives an EventArgs instance, which does not by default contain any additional information.

We will discuss events and delegates in more detail later in the book, most notably in chapters 3 and 9. For now, simply recognize that OnLoadClick is an event handler that is invoked whenever the user clicks the Load button.

The next section looks at the implementation of the OnLoadClick method in more detail.

1.3.2The OpenFileDialog class

Once our OnLoadClick event handler is registered, we are ready to load a new image into the application. The signature of the OnLoadClick method must match the signature of the EventHandler delegate by being a void function that accepts an object and EventArgs parameter. Note how this is a private method so that it is not available except within the MyForm class.

private void OnLoadClick(object sender, System.EventArgs e)

{

OpenFileDialog dlg = new OpenFileDialog();

dlg.Title = "Open Photo";

dlg.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ;

if (dlg.ShowDialog() == DialogResult.OK)

{

pboxPhoto.Image = new Bitmap(dlg.OpenFile());

}

dlg.Dispose();

}

22

CHAPTER 1 GETTING STARTED WITH WINDOWS FORMS

The System.Windows.Forms.OpenFileDialog class is used to prompt the user to select an image to display. This class inherits from the more generic FileDialog class, which provides a standard framework for reading and writing files. A summary of this class is given in .NET Table 1.2.

OpenFileDialog dlg = new OpenFileDialog();

dlg.Title = "Open Photo";

dlg.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ;

The Title property for this class sets the string displayed in the title bar of the dialog, while the Filter property defines the list of file types that can be seen in the dialog. The format of the Filter property matches the one used for file dialogs in previous Microsoft environments. The vertical bar character ‘|’ separates each part of the string. Each pair of values in the string represents the string to display in the dialog and the regular expression to use when displaying files, respectfully. In our example, the dialog box presents two options for the type of file to select. This first is “jpg files (*.jpg)” which will match all files of the form *.jpg; while the second is “All files (*.*)” which will match all files of the form *.*.

Once the OpenFileDialog object is created and initialized, the ShowDialog method displays the dialog and waits for the user to select a file. This method returns a member of the DialogResult enumeration, which identifies the button selected by the user.

if (dlg.ShowDialog() == DialogResult.OK)

{

pboxPhoto.Image = new Bitmap(dlg.OpenFile());

}

If the user clicks the OK button, the ShowDialog method returns the value DialogResult.OK. If the user clicks the Cancel button, the ShowDialog method returns the value DialogResult.Cancel. When the OK button has been clicked, the selected file is loaded as a Bitmap object, which is our next topic.

TRY IT! Note that no error handling is performed by our code. Try selecting a nonimage file in the dialog to see how the program crashes and burns. We will talk about handling such errors in the next chapter.

Before we move on, note the final line of our OnLoadClick handler.

dlg.Dispose();

While the garbage collector frees us from worrying about memory cleanup, nonmemory resources are still an issue. In this case, our OpenFileDialog object allocates operating system resources to display the dialog and file system resources to open the file via the OpenFile method. While the garbage collector may recover these resources eventually, such resources may be limited and should always be reclaimed manually by calling the Dispose method.

LOADING FILES

23

.

.NET Table 1.2 FileDialog class

The FileDialog class is a common dialog that supports interacting with files on disk. This class is abstract, meaning you cannot create an instance of it, and serves as the base class for the OpenFileDialog and SaveFileDialog class. The FileDialog class is part of the System.Windows.Forms namespace and inherits from the CommonDialog class.

Note that a FileDialog object should call the Dispose method when finished to ensure that nonmemory resources such as file and window handles are cleaned up properly.

 

AddExtension

Gets or sets whether the dialog box automatically

 

 

adds the file extension if omitted by the user.

 

CheckFileExists

Gets or sets whether the dialog box displays a

 

 

warning if the specified file does not exist.

 

FileName

Gets or sets the string containing the selected file

 

 

name.

 

FileNames

Gets the array of strings containing the set of files

 

 

selected (used when the

 

 

OpenFileDialog.Multiselect property is true).

Public Properties

Filter

Gets or sets the file name filter string, which

 

 

 

determines the file type choices for a file dialog box.

 

InitialDirectory

Gets or sets the initial directory displayed by the file

 

 

dialog box.

 

RestoreDirectory

Gets or sets whether the dialog box restores the

 

 

current directory to its original value before closing.

 

ShowHelp

Gets or sets whether the Help button appears on the

 

 

dialog.

 

Title

Gets or sets the title bar string for the dialog box.

 

 

 

 

Reset

Resets all properties for the dialog box to their

 

 

default values.

Public Methods

ShowDialog

Displays a common dialog box and returns the

 

 

(inherited from

DialogResult enumeration value of the button

 

CommonDialog)

selected by the user.

 

 

 

 

FileOk

Occurs when the Open or Save button is clicked on a

 

 

file dialog box.

Public Events

HelpRequested

Occurs when the Help button is clicked on a

 

 

(inherited from

common dialog box.

 

CommonDialog)

 

 

 

 

The Dispose method is the standard mechanism for cleaning up such resources. We will discuss this method in more detail in chapter 6.

1.3.3Bitmap images

So far we have discussed how our application responds to a click of the Load button and enables the user to select an image file. When the user clicks the OK button in the open file dialog box, the OnLoadClick method loads an image into the

24

CHAPTER 1 GETTING STARTED WITH WINDOWS FORMS

Pic-

PictureBox control. It does this by creating a new Bitmap object for the selected file and assigning it to the Image property of the PictureBox control.

if (dlg.ShowDialog() == DialogResult.OK)

{

pboxPhoto.Image = new Bitmap(dlg.OpenFile());

}

The support for image files has been steadily improving with each new development environment from Microsoft, and the .NET Framework is no exception. While the

.NET classes do not provide all the functionality you might like (as we shall see), it does provide a number of improvements over the previous support provided by the MFC (Microsoft Foundation Class) library. One of them is the PictureBox control to make image display a little easier. All we have to do is set the Image property to a bitmap image and the framework takes care of the rest.

Our friend, the new keyword, creates the Bitmap. Once again, we see how garbage collection makes our life easier. In C++, the memory allocated for this Bitmap would need to be tracked and eventually freed with a call to delete. In C#, we create the object and forget about it, relying on the garbage collector to clean it up when a new image is loaded by the OnLoadClicked method and the existing Bitmap replaced.

The OpenFileDialog class provides a couple of ways to access the selected file. The FileName property retrieves the path to the selected file. In our code, we opt for the OpenFile method to open this file with read-only permission. The open file is passed to the Bitmap constructor to load the image.

The constructed bitmap is assigned to the Image property of our pboxPhoto variable. This property can hold any object which is based on the Image class, including bitmaps, icons, and cursors.

How this image appears within the picture box control depends on the tureBox.SizeMode property. In our case, we set this property so that the image is shrunk and/or expanded to fit the boundaries of the PictureBox control.

pboxPhoto.SizeMode = PictureBoxSizeMode.StretchImage;

TRY IT! If you’re feeling slightly adventurous, you should now be able to add a second Button and second PictureBox to the form. Label the second button “Load2” and implement an OnLoad2Click event handler that loads a second image into the second PictureBox control.

As an alternate modification, change the Main method to receive the array of command-line arguments passed to the program in an args variable. Load the first parameter in args[0] as a Bitmap object and assign it to the PictureBox control for the MyForm class. To do this, you will need to add a new constructor to the MyForm class that receives the name of an image file.

LOADING FILES

25

Соседние файлы в папке c#