Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Visual CSharp 2005 Recipes (2006) [eng]

.pdf
Скачиваний:
48
Добавлен:
16.08.2013
Размер:
4.04 Mб
Скачать

248 C H A P T E R 7 W I N D O W S F O R M S

protected override void OnLoad(EventArgs e)

{

//Call the OnLoad method of the base class to ensure the Load

//event is raised correctly.

base.OnLoad(e);

// Load the basic set of eight icons. images[0] = new Icon("moon01.ico"); images[1] = new Icon("moon02.ico"); images[2] = new Icon("moon03.ico"); images[3] = new Icon("moon04.ico"); images[4] = new Icon("moon05.ico"); images[5] = new Icon("moon06.ico"); images[6] = new Icon("moon07.ico"); images[7] = new Icon("moon08.ico");

}

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

{

//Change the icon. This event handler fires once every second

//(1000 ms).

notifyIcon.Icon = images[offset]; offset++;

if (offset > 7) offset = 0;

}

[STAThread]

public static void Main(string[] args)

{

Application.Run(new Recipe07_16());

}

}

}

7-17. Validate an Input Control

Problem

You need to alert the user of invalid input in a control, such as a TextBox.

Solution

Use the ErrorProvider component to display an error icon next to the offending control. Check for errors before allowing the user to continue.

How It Works

You can perform validation in a Windows-based application in a number of ways. One approach is to refuse any invalid character as the user presses a key, by using a MaskedTextBox control, as shown in recipe 7-8. Another approach is to respond to control validation events and prevent users from changing focus from one control to another if an error exists. A less invasive approach is to simply flag the offending control in some way, so that the user can review all the errors at once. You can use this approach by adding the ErrorProvider component to your form.

C H A P T E R 7 W I N D O W S F O R M S

249

The ErrorProvider is a special property extender component that displays error icons next to invalid controls. You show the error icon next to a control by using the ErrorProvider.SetError method and specifying the appropriate control and a string error message. The ErrorProvider will then show a warning icon to the right of the control. When the user hovers the mouse above the warning icon, the detailed message appears.

You need to add only one ErrorProvider component to your form, and you can use it to display an error icon next to any control. To add the ErrorProvider, drag it on the form or into the component tray, or create it manually in code.

The Code

The following example checks the value that a user has entered into a textbox whenever the textbox loses focus. The code validates this textbox using a regular expression that checks to see if the value corresponds to the format of a valid e-mail address (see recipe 2-5 for more details on regular expressions). If validation fails, the ErrorProvider is used to display an error message. If the text is valid, any existing error message is cleared from the ErrorProvider. Finally, the Click event handler for the OK button steps through all the controls on the form and verifies that none of them have errors before allowing the example to continue. In this example, an empty textbox is allowed, although it would be a simple matter to perform additional checks when the OK button is pressed for situations where empty textboxes are not acceptable.

using System;

using System.Windows.Forms;

using System.Text.RegularExpressions;

namespace Apress.VisualCSharpRecipes.Chapter07

{

public partial class Recipe07_17 : Form

{

public Recipe07_17()

{

//Initialization code is designer generated and contained

//in a separate file using the C# 2.0 support for partial

//classes.

InitializeComponent();

}

//Button click event handler ensures the ErrorProvider is not

//reporting any error for each control before proceeding. private void Button1_Click(object sender, EventArgs e)

{

string errorText = ""; bool invalidInput = false;

foreach (Control ctrl in this.Controls)

{

if (errProvider.GetError(ctrl) != "")

{

errorText += " * " + errProvider.GetError(ctrl) + "\n"; invalidInput = true;

}

}

if (invalidInput)

{

MessageBox.Show(

250 C H A P T E R 7 W I N D O W S F O R M S

"The form contains the following unresolved errors:\n\n" + errorText, "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Warning);

}

else

{

this.Close();

}

}

//When the TextBox loses focus, check that the contents are a valid

//e-mail address.

private void txtEmail_Leave(object sender, EventArgs e)

{

//Create a regular expression to check for valid e-mail addresses. Regex regex;

regex = new Regex(@"^[\w-]+@([\w-]+\.)+[\w-]+$");

//Validate the text from the control that raised the event. Control ctrl = (Control)sender;

if (regex.IsMatch(ctrl.Text) || ctrl.Text == "")

{

errProvider.SetError(ctrl, "");

}

else

{

errProvider.SetError(ctrl, "This is not a valid email address.");

}

}

[STAThread]

public static void Main(string[] args)

{

Application.Run(new Recipe07_17());

}

}

}

Usage

Figure 7-13 shows how the ErrorProvider control indicates an input error for the TextBox control when Recipe07-17 is run.

Figure 7-13. A validated form with the ErrorProvider

C H A P T E R 7 W I N D O W S F O R M S

251

7-18. Use a Drag-and-Drop Operation

Problem

You need to use the drag-and-drop feature to exchange information between two controls (possibly in separate windows or in separate applications).

Solution

Start a drag-and-drop operation using the DoDragDrop method of the Control class, and then respond to the DragEnter and DragDrop events.

How It Works

A drag-and-drop operation allows the user to transfer information from one place to another by clicking an item and dragging it to another location. A drag-and-drop operation consists of the following three basic steps:

1.The user clicks a control, holds down the mouse button, and begins dragging. If the control supports the drag-and-drop feature, it sets aside some information.

2.The user drags the mouse over another control. If this control accepts the dragged type of content, the mouse cursor changes to the special drag-and-drop icon (arrow and page). Otherwise, the mouse cursor becomes a circle with a line drawn through it.

3.When the user releases the mouse button, the data is sent to the control, which can then process it appropriately.

To support drag-and-drop functionality, you must handle the DragEnter, DragDrop, and (typically) MouseDown events. To start a drag-and-drop operation, you call the source control’s DoDragDrop method. At this point, you submit the data and specify the type of operations that will be supported (copying, moving, and so on). Controls that can receive dragged data must have the AllowDrop property set to true. These controls will receive a DragEnter event when the mouse drags the data over them. At this point, you can examine the data that is being dragged, decide whether the control can accept the drop, and set the DragEventArgs.Effect property accordingly. The final step is to respond to the DragDrop event, which occurs when the user releases the mouse button.

Note It is very important that the Main method of your Windows application be annotated with the STAThread attribute if your application will provide drag-and-drop functionality.

The Code

The following example allows you to drag content between two textboxes, as well as to and from other applications that support drag-and-drop operations.

using System;

using System.Windows.Forms;

namespace Apress.VisualCSharpRecipes.Chapter07

{

public partial class Recipe07_18 : Form

{

252 C H A P T E R 7 W I N D O W S F O R M S

public Recipe07_18()

{

//Initialization code is designer generated and contained

//in a separate file using the C# 2.0 support for partial

//classes.

InitializeComponent();

}

private void TextBox_MouseDown(object sender, MouseEventArgs e)

{

TextBox txt = (TextBox)sender; txt.SelectAll();

txt.DoDragDrop(txt.Text, DragDropEffects.Copy);

}

private void TextBox_DragEnter(object sender, DragEventArgs e)

{

if (e.Data.GetDataPresent(DataFormats.Text))

{

e.Effect = DragDropEffects.Copy;

}

else

{

e.Effect = DragDropEffects.None;

}

}

private void TextBox_DragDrop(object sender, DragEventArgs e)

{

TextBox txt = (TextBox)sender;

txt.Text = (string)e.Data.GetData(DataFormats.Text);

}

[STAThread]

public static void Main(string[] args)

{

Application.Run(new Recipe07_18());

}

}

}

7-19. Use Context-Sensitive Help

Problem

You want to display a specific help file topic depending on the currently selected control.

Solution

Use the System.Windows.Forms.HelpProvider component, and set the HelpKeyword and HelpNavigator extended properties for each control.

C H A P T E R 7 W I N D O W S F O R M S

253

How It Works

The .NET Framework provides support for context-sensitive help through the HelpProvider class. The HelpProvider class is a special extender control. You add it to the component tray of a form, and it extends all the controls on the form with a few additional properties, including HelpNavigator and HelpKeyword. For example, Figure 7-14 shows a form that has two controls and a HelpProvider named helpProvider1. The ListBox control, which is currently selected, has several help-specific properties that are provided through HelpProvider.

Figure 7-14. The HelpProvider extender properties

To use context-sensitive help with HelpProvider, you simply need to follow these three steps:

1.Set the HelpProvider.HelpNamespace property with the name of the help file. (For example, an HTML help file might be named myhelp.chm.)

2.For every control that requires context-sensitive help, set the HelpNavigator extender property to HelpNavigator.Topic.

3.For every control that requires context-sensitive help, set the HelpKeyword extender property with the name of the topic that should be linked to this control. (The topic names are specific to the help file and can be configured in your help authoring tools.)

If the user presses the F1 key while a control has focus, the help file will be launched automatically, and the linked topic will be displayed in the help window. If the user presses F1 while positioned on a control that does not have a linked help topic, the help settings for the containing control will be used (for example, a group box or a panel). If there are no containing controls or the containing control does not have any help settings, the form’s help settings will be used. You can also use the HelpProvider methods to set or modify context-sensitive help mapping at runtime.

254 C H A P T E R 7 W I N D O W S F O R M S

7-20. Display a Web Page in a Windows-Based

Application

Problem

You want to display a web page and provide web-navigation capabilities within your Windows Forms application.

Solution

Use the WebBrowser control to display the web page and other standard controls like buttons and textboxes to allow the user to control the operation of the WebBrowser.

Caution The WebBrowser control is a managed wrapper around the WebBrowser ActiveX control. This means that you must ensure you annotate the Main method of your Windows application with the STAThread attribute.

How It Works

The WebBrowser control (new to .NET Framework 2.0) makes it a trivial task to embed highly functional web browser capabilities into your Windows applications. The WebBrowser control is responsible for the display of web pages and maintaining page history, but it does not provide any controls for user interaction. Instead, the WebBrowser control exposes properties and events that you can manipulate programmatically to control the operation of the WebBrowser. This approach makes the WebBrowser control highly flexible and adaptable to almost any situation. Table 7-1 summarizes some of the WebBrowser members related to web navigation that you will find particularly useful.

Table 7-1. Commonly Used Members of the WebBrowser Control

Member

Description

Property

 

AllowNavigation

Controls whether the WebBrowser can navigate to another page after its

 

initial page has been loaded

CanGoBack

Indicates whether the WebBrowser currently holds back page history,

 

which would allow the GoBack method to succeed

CanGoForward

Indicates whether the WebBrowser currently holds forward page history,

 

which would allow the GoForward method to succeed

IsBusy

Indicates whether the WebBrowser is currently busy downloading a page

Url

Holds the URL of the currently displayed/downloading page

Method

 

GoBack

Displays the previous page in the page history

GoForward

Displays the next page in the page history

GoHome

Displays the home page of the current user as configured in Windows

Navigate

Displays the web page at the specified URL

Stop

Stops the current WebBrowser activity

Event

 

DocumentCompleted

Signals that the active download has completed and the document is

 

displayed in the WebBrowser

 

 

C H A P T E R 7 W I N D O W S F O R M S

255

You can also use the WebBrowser.DocumentText property to set (or get) the currently displayed HTML contents of the WebBrowser. To manipulate the contents using the Document Object Model (DOM), get an HtmlDocument instance via the Document property.

The Code

The following example uses the WebBrowser control to allow users to navigate to a web page whose address is entered into a TextBox. Buttons also allow users to move forward and backward through page history and navigate directly to their personal home page.

using System;

using System.Windows.Forms;

namespace Apress.VisualCSharpRecipes.Chapter07

{

public partial class Recipe07_20 : Form

{

public Recipe07_20()

{

//Initialization code is designer generated and contained

//in a separate file using the C# 2.0 support for partial

//classes.

InitializeComponent();

}

private void goButton_Click(object sender, EventArgs e)

{

// Navigate to the URL specified in the textbox. webBrowser1.Navigate(textURL.Text);

}

private void homeButton_Click(object sender, EventArgs e)

{

// Navigate to the current user's home page. webBrowser1.GoHome();

}

protected override void OnLoad(EventArgs e)

{

//Call the OnLoad method of the base class to ensure the Load

//event is raised correctly.

base.OnLoad(e);

//Navigate to the Apress home page when the application first

//loads.

webBrowser1.Navigate("http://www.apress.com");

}

private void backButton_Click(object sender, EventArgs e)

{

// Go to the previous page in the WebBrowser history. webBrowser1.GoBack();

}

256 C H A P T E R 7 W I N D O W S F O R M S

private void forwarButton_Click(object sender, EventArgs e)

{

// Go to the next page in the WebBrowser history. webBrowser1.GoForward();

}

//Event handler to perform general interface maintenance once a document

//has been loaded into the WebBrowser.

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)

{

//Update the content of the TextBox to reflect the current URL. textURL.Text = webBrowser1.Url.ToString();

//Enable or disable the Back button depending on whether the

//WebBrowser has back history.

if (webBrowser1.CanGoBack)

{

backButton.Enabled = true;

}

else

{

backButton.Enabled = false;

}

//Enable or disable the Forward button depending on whether the

//WebBrowser has forward history.

if (webBrowser1.CanGoForward)

{

forwarButton.Enabled = true;

}

else

{

forwarButton.Enabled = false;

}

}

[STAThread]

public static void Main(string[] args)

{

Application.Run(new Recipe07_20());

}

}

}

C H A P T E R 8

■ ■ ■

Graphics, Multimedia, and Printing

Graphics, video, sound, and printing are the hallmarks of a traditional rich client on the Microsoft Windows operating system. When it comes to multimedia, the Microsoft .NET Framework delivers a compromise, providing support for some of these features while ignoring others. For example, you will find a sophisticated set of tools for two-dimensional drawing and event-based printing with GDI+ and the types in the System.Drawing namespaces. These classes wrap GDI32.dll and USER32.dll, which provide the native Graphics Device Interface (GDI) functions in the Windows application programming interface (API), and they make it much easier to draw complex shapes, work with coordinates and transforms, and process images. On the other hand, if you want to show a video file or get information about the current print jobs, you will need to look beyond the

.NET Framework.

This chapter presents recipes that show you how to use built-in .NET features and, where necessary, native Win32 libraries via P/Invoke or COM Interop. The recipes in this chapter describe how to do the following:

Find the fonts installed in your system (recipe 8-1)

Perform hit testing with shapes (recipe 8-2)

Create an irregularly shaped form or control (recipe 8-3)

Create a sprite that could be moved around (recipe 8-4)

Display an image that could be made to scroll (recipe 8-5), learn how to capture the image of the desktop (recipe 8-6), and create a thumbnail for an existing image (recipe 8-8)

Enable double buffering to increase performance while redrawing (recipe 8-7)

Play a beep or a system-defined sound (recipe 8-9), play a WAV file (recipe 8-10), play a non-WAV file such as an MP3 file (recipe 8-11), and play an animation with DirectShow (recipe 8-12)

Retrieve information about the printers installed in the machine (recipe 8-13), print a simple document (recipe 8-14), print a document having multiple pages (recipe 8-15), print wrapped text (recipe 8-16), show a print preview (recipe 8-17), and manage print jobs (recipe 8-18)

8-1. Find All Installed Fonts

Problem

You need to retrieve a list of all the fonts installed on the current computer.

257

Соседние файлы в предмете Программирование на C++