1. Trang chủ
  2. » Công Nghệ Thông Tin

Visual C# 2010 Recipes solution_3 potx

95 554 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 95
Dung lượng 2,09 MB

Nội dung

CHAPTER 7 ■ WINDOWS FORMS 355 synchronously and BeginInvoke executes the delegate asynchronously. To complete an asynchronous operation initiated using BeginInvoke, you call the Control.EndInvoke method. The BeginInvoke and EndInvoke methods make up a common asynchronous execution pattern known as the Classic Async pattern. The details of this pattern and the options you have available for handling method completion are discussed in recipe 4-2. The Code The following example shows how to update a Windows Forms control from multiple threads. The example uses two timers that fire at differing intervals to change the color of a Button control between red and green. The code shows how to use both an anonymous method and a lambda expression with the Invoke call. Both approaches use System.Action, a delegate type that can encapsulate any method that returns void and takes no arguments. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Apress.VisualCSharpRecipes.Chapter07 { public partial class Recipe07_19 : Form { // Declare timers that change the button color. System.Timers.Timer greenTimer; System.Timers.Timer redTimer; public Recipe07_19() { // Initialization code is designer generated and contained // in a separate file named Recipe07-19.Designer.cs. InitializeComponent(); // Create autoreset timers that fire at varying intervals // to change the color of the button on the form. greenTimer = new System.Timers.Timer(3000); greenTimer.Elapsed += new System.Timers.ElapsedEventHandler(greenTimer_Elapsed); greenTimer.Start(); redTimer = new System.Timers.Timer(5000); redTimer.Elapsed += new System.Timers.ElapsedEventHandler(redTimer_Elapsed); redTimer.Start(); } CHAPTER 7 ■ WINDOWS FORMS 356 void redTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // Use an anonymous method to set the button color to red. button1.Invoke((Action)delegate {button1.BackColor = Color.Red;}); } void greenTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // Use a lambda expression to set the button color to green. button1.Invoke(new Action(() => button1.BackColor = Color.Green)); } private void button1_Click(object sender, EventArgs e) { Application.Exit(); } [STAThread] public static void Main(string[] args) { Application.Run(new Recipe07_19()); } } } 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 text boxes 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 and that you dispose of the WebBrowser control (by calling the WebBrowser.Dispose method) when it is no longer required. CHAPTER 7 ■ WINDOWS FORMS 357 How It Works The WebBrowser control 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 most common browsing requirements. 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 CHAPTER 7 ■ WINDOWS FORMS 358 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 named Recipe07-20.Designer.cs. InitializeComponent(); } private void goButton_Click(object sender, EventArgs e) { // Navigate to the URL specified in the text box. 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"); } CHAPTER 7 ■ WINDOWS FORMS 359 private void backButton_Click(object sender, EventArgs e) { // Go to the previous page in the WebBrowser history. webBrowser1.GoBack(); } 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()); } } } CHAPTER 7 ■ WINDOWS FORMS 360 7-21. Display WPF Windows in a Windows Forms Application Problem You need to display a WPF window in a Windows Forms application. Solution Create an instance of the WPF window (System.Windows.Window) you want to display in your Windows Forms code. Call Window.ShowDialog to display a modal window, or call Window.Show to display a modeless window. How It Works The trickiest thing about displaying a WPF window in a Windows Forms application is actually integrating the WPF source code into your project correctly if you are using Visual Studio. There is no option in your Windows Forms project to add a WPF Window when you select Add New Item in Solution Explorer. The easiest way around this is to import an existing WPF Window using the Add Existing option in Solution Explorer. This will set everything up appropriately (adding the necessary assembly references), and you can then edit the WPF Window as you would when creating a WPF application. Alternatively, Visual Studio will allow you to add a new WPF user control to your Windows Forms application. You can use that option and then change the XAML and code-behind as required. Once you have a WPF Window declared, you can reference and instantiate the class the same as you would any other class. Calling Window.ShowDialog will display the window modally, meaning that the user can interact with only that window and must close it before they can interact again with the rest of the application. Calling Window.Show will display a modeless window, allowing the user to interact with the new window as well as the rest of the application. The Code The following example (shown running in Figure 7-13) displays a Windows Form with two buttons. The left button opens and closes a modeless WPF window, and the right button opens a modal window. When the example creates the modeless window, it subscribes an event handler to the Window.Closing event so that the application can update the button state should the user choose to close the window directly instead of using the button. The following code is the code-behind for the main Windows Form: using System; using System.ComponentModel; using System.Windows.Forms; namespace Apress.VisualCSharpRecipes.Chapter07 { public partial class Recipe07_21 : Form { private Window1 modelessWindow; CHAPTER 7 ■ WINDOWS FORMS 361 private CancelEventHandler modelessWindowCloseHandler; public Recipe07_21() { // Initialization code is designer generated and contained // in a separate file named Recipe07-21.Designer.cs. InitializeComponent(); modelessWindowCloseHandler = new CancelEventHandler(Window_Closing); } // Handles the button click event to open and close the modeless // WPF window. private void OpenModeless_Click(object sender, EventArgs e) { if (modelessWindow == null) { modelessWindow = new Window1(); // Add an event handler to get notification when the window // is closing. modelessWindow.Closing += modelessWindowCloseHandler; // Change the button text. btnOpenModeless.Text = "Close Modeless Window"; // Show the Windows Form. modelessWindow.Show(); } else { modelessWindow.Close(); } } // Handles the button click event to open the modal WPF Window. private void OpenModal_Click(object sender, EventArgs e) { // Create and display the modal window. Window1 window = new Window1(); window.ShowDialog(); } // Handles the WPF Window's Closing event for the modeless window. private void Window_Closing(object sender, CancelEventArgs e) { // Remove the event handler reference. modelessWindow.Closing -= modelessWindowCloseHandler; modelessWindow = null; CHAPTER 7 ■ WINDOWS FORMS 362 // Change the button text. btnOpenModeless.Text = "Open Modeless Window"; } } } The following XAML provides the declaration of the WPF Window that is opened when the user clicks either of the buttons on the Windows Forms application: <Window x:Class="Apress.VisualCSharpRecipes.Chapter07.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Recipe07_21" Height="200" Width="300"> <StackPanel Margin="20"> <TextBlock FontSize="20" Text="A WPF Window" TextAlignment="Center"/> <Button Click="btnClose_Click" Content="Close" Margin="50" MaxWidth="50" Name="btnClose" /> </StackPanel> </Window> The following is the code-behind for the WPF Window that allows the user to close the window by clicking the Close button: using System.Windows; using System.Windows.Forms; namespace Apress.VisualCSharpRecipes.Chapter07 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void btnClose_Click(object sender, RoutedEventArgs e) { this.Close(); } } } CHAPTER 7 ■ WINDOWS FORMS 363 Figure 7-13. Displaying a WPF window from a Windows Forms application 7-22. Display WPF Controls in Windows Forms Problem You need to display WPF user interface elements alongside Windows Forms controls in a Windows Form. Solution Use a System.Windows.Forms.Integration.ElementHost control on your Windows Form, and host the WPF control inside it. How It Works The ElementHost control is a Windows Forms control that allows you to host WPF controls in Windows Forms. The ElementHost control makes integrating WPF controls into your Windows Forms application relatively simple and even provides some limited visual design-time support. The ElementHost can contain a single WPF element that inherits from System.Windows.UIElement. The element can be one of the layout containers discussed in Chapter 17, which allows you to create rich, structured WPF content within the ElementHost control. Often, the WPF element you place in the ElementHost control will be a WPF user control (see Chapter 17), but can also be any common WPF control. To use the ElementHost control in Visual Studio’s graphical design environment, open the toolbox and browse to the WPF Interoperability category. Drag the ElementHost control and drop it on the Windows Form as you would with any other control. Using the ElementHost Tasks window, you can then select any WPF user control currently in your project to place in the ElementHost control (see Figure 7-14). CHAPTER 7 ■ WINDOWS FORMS 364 Figure 7-14. Using ElementHost in Visual Studio If you do not want to use a user control, then you will need to populate the ElementHost control programmatically by assigning the desired WPF element to the Child property of the ElementHost control. The Code The following example demonstrates how to integrate WPF controls into a Windows Forms application. The example (shown in Figure 7-15) uses a simple WPF user control consisting of a System.Windows. Shapes.Ellipse that can change between red and blue color gradients. This EllipseControl is assigned to one ElementHost using the Visual Studio form builder. Another ElementHost is populated programmatically with a System.Windows.Controls.TextBox. A standard Windows Forms button triggers the EllipseControl to change color, and then writes a log entry to the TextBox. Here is the XAML for the WPF user control: <UserControl x:Class="Apress.VisualCSharpRecipes.Chapter07.EllipseControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300"> <Grid x:Name="Grid1"> <Grid.Resources> <RadialGradientBrush x:Key="RedBrush" RadiusX=".8" RadiusY="1" Center="0.5,0.5" GradientOrigin="0.05,0.5"> <GradientStop Color="#ffffff" Offset="0.1" /> <GradientStop Color="#ff0000" Offset="0.5" /> <GradientStop Color="#880000" Offset="0.8" /> </RadialGradientBrush> <RadialGradientBrush x:Key="BlueBrush" RadiusX=".8" RadiusY="1" Center="0.5,0.5" GradientOrigin="0.05,0.5"> <GradientStop Color="#ffffff" Offset="0.1" /> <GradientStop Color="#0000ff" Offset="0.5" /> <GradientStop Color="#000088" Offset="0.8" /> </RadialGradientBrush> </Grid.Resources> [...]... The rest of the application code generated by Visual Studio is not shown here, but is provided in the sample code (available on the book’s page on the Apress web site, www.apress.com) using using using using using System; System.Windows; System.Windows.Forms; WPFControls=System.Windows.Controls; System.Windows.Forms.Integration; namespace Apress.VisualCSharpRecipes.Chapter07 { public partial class Recipe07_22:... Here is the code-behind for the EllipseControl, which is used to control and query its current color gradient: using System.Windows.Controls; using System.Windows.Media; namespace Apress.VisualCSharpRecipes.Chapter07 { /// /// Interaction logic for EllipseControl.xaml /// public partial class EllipseControl : UserControl { public EllipseControl() { // Initialization code... 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... AutoScroll set to true, allowing the user to scroll through the list of available fonts using using using using System; System.Drawing; System.Windows.Forms; System.Drawing.Text; namespace Apress.VisualCSharpRecipes.Chapter08 { public partial class Recipe08_01: Form { public Recipe08_01() { InitializeComponent(); } private void Recipe08_01_Load(object sender, EventArgs e) { 370 CHAPTER 8 ■ GRAPHICS,... lead to more drawing and generate additional flicker as the entire form is repainted using using using using System; System.Drawing; System.Windows.Forms; System.Drawing.Drawing2D; namespace Apress.VisualCSharpRecipes.Chapter08 { public partial class Recipe08_02 : Form { // Define the shapes used on this form private GraphicsPath path; private Rectangle rectangle; // Define the flags that track where the... are converted into a closed figure using the GraphicsPath.CloseAllFigures method using using using using System; System.Drawing; System.Windows.Forms; System.Drawing.Drawing2D; namespace Apress.VisualCSharpRecipes.Chapter08 { public partial class Recipe08_03 : Form { public Recipe08_03() { InitializeComponent(); } private void Recipe08_03_Load(object sender, EventArgs e) { GraphicsPath path = new GraphicsPath();... the entire client rectangle The following code shows the full EllipseShape code: using using using using System; System.Drawing; System.Windows.Forms; System.Drawing.Drawing2D; namespace Apress.VisualCSharpRecipes.Chapter08 { public partial class EllipseShape : Control { public EllipseShape() { InitializeComponent(); } private GraphicsPath path = null; 379 CHAPTER 8 ■ GRAPHICS, MULTIMEDIA, AND PRINTING... Microsoft Visual Studio NET toolbox and use it at design time However, even without taking this step, it is easy to create a simple test application The following Windows Forms application creates two ellipses and allows the user to drag both of them around the form, simply by holding the mouse down and moving the pointer: using System; using System.Drawing; using System.Windows.Forms; namespace Apress.VisualCSharpRecipes.Chapter08... Graphics.DrawString method The image is then bound to a picture box, which is shown in a scrollable panel, as shown in Figure 8-5 using System; using System.Drawing; using System.Windows.Forms; namespace Apress.VisualCSharpRecipes.Chapter08 { public partial class Recipe08_05 : Form { public Recipe08_05() { InitializeComponent(); } private void Recipe08_05_Load(object sender, EventArgs e) { string text = "The quick... CopyFromScreen to draw onto the Bitmap After drawing, the image is assigned to the picture box, as shown in Figure 8-6 using System; using System.Drawing; using System.Windows.Forms; namespace Apress.VisualCSharpRecipes.Chapter08 { public partial class Recipe08_06 : Form { public Recipe08_06() { InitializeComponent(); } private void cmdCapture_Click(object sender, EventArgs e) { Bitmap screen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, . System.Windows.Forms; namespace Apress.VisualCSharpRecipes.Chapter07 { public partial class Recipe07_21 : Form { private Window1 modelessWindow; CHAPTER 7 ■ WINDOWS FORMS 36 1 private CancelEventHandler. sender, RoutedEventArgs e) { this.Close(); } } } CHAPTER 7 ■ WINDOWS FORMS 36 3 Figure 7- 13. Displaying a WPF window from a Windows Forms application 7-22. Display WPF Controls. 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

Ngày đăng: 20/06/2014, 08:20