Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
406,06 KB
Nội dung
616 CHAPTER 18 ODDS AND ENDS .NET 6 Add a Paint event handler for the PictureBox control to do the following: a. If the current position is out of range, simply return. b. Load the current Photograph. c. Display the caption in the title bar. d. Preserve the aspect ratio when drawing the image into the window. private void pboxSlide_Paint (object sender, System.Windows.Forms.PaintEventArgs e) { if (_albumPos >= _album.Count) return; Photograph photo = _album[_albumPos]; if (photo != null) { this.Text = String.Format("{0} ({1:#}/{2:#})", photo.Caption, _albumPos + 1, _album.Count); e.Graphics.DrawImage(photo.Image, photo.ScaleToFit( pboxSlide.ClientRectangle)); } else e.Graphics.Clear(SystemColors.Control); } 7 Add a Tick event handler for the slideTimer component. How-to This is the default event for this component, so simply double-click the timer in the component tray. private void slideTimer_Tick (object sender, System.EventArgs e) { 8 In this handler, increment the current album position. _albumPos ++; 9 If the position is passed the end of the album, reset the slide show as follows: a. Modify the Stop button text to be Start. b. Reset the track bar value to zero. c. Invalidate the picture box to draw the initial photograph. d. Disable the timer. if (_albumPos > _album.Count) { btnStop.Text = "&Start"; _albumPos = 0; trackSlide.Value = 0; pboxSlide.Invalidate(); slideTimer.Enabled = false; } 10 If the position is at the end of the album, set the title bar to indicate the slide show is finished. else if (_albumPos == _album.Count) { this.Text = "Finished"; } 11 Otherwise, for a valid album index: a. Invalidate the picture box to draw the next image. b. Set the track bar value to the cur- rent position. else { pboxSlide.Invalidate(); trackSlide.Value = _albumPos; } 12 Reassign the interval value to pick up any changes made by the user. // Reset the interval SetInterval(); } IMPLEMENT THE SLIDE SHOW BEHAVIOR (continued) Action Result TIMERS 617 13 Add a Click event handler for the Close button to close the form. private void btnClose_Click (object sender, System.EventArgs e) { this.Close(); } 14 Add a Click event handler for the Stop button. private void btnStop_Click (object sender, System.EventArgs e) { 15 If the current Text value is Stop, stop the timer and set the button text to Resume. Note: While our Stop button has three different display strings, we preserve the keyboard access key of Alt+S in all three values. if (btnStop.Text == "&Stop") { // Stop slideTimer.Stop(); btnStop.Text = "Re&sume"; } 16 For other text values, start the timer and set the button text to Stop. else { // Resume or Start slideTimer.Start(); btnStop.Text = "&Stop"; } } 17 Add a Scroll event handler for the TrackBar control. Note: This is the default event for the track bar control, and occurs when the user manually adjusts the slider position. private void trackSlide_Scroll (object sender, System.EventArgs e) { 18 In this handler: a. Set the album position to the new value. b. Invalidate the picture box to draw the selected photo. _albumPos = trackSlide.Value; pboxSlide.Invalidate(); } 19 Add a Resize event handler for the PictureBox control to invalidate the control and redraw the image. private void pboxSlide_Resize (object sender, System.EventArgs e) { pboxSlide.Invalidate(); } 20 Back in the MainForm class, add a Click event handler for the Slide Show menu to create and display a SlideShowForm dialog. private void menuSlideShow_Click (object sender, System.EventArgs e) { using (SlideShowForm f = new SlideShowForm(_album)) { // Display slide show as modal dialog f.ShowDialog(); } } IMPLEMENT THE SLIDE SHOW BEHAVIOR (continued) Action Result 618 CHAPTER 18 ODDS AND ENDS .NET The slide show form is now fully integrated into our main application. Compile and run to see this window. Load an album and select the Slide Show menu to display the new dialog. TRY IT! Throughout the book we have used the photo album and photograph ab- stractions we constructed in chapter 5 to represent and display images. In the MyPhotos application we display photographs in a Panel control, while in our other applications we use a PictureBox control. In both cas- es we were forced to override the Paint event in order to draw a photo- graph with the proper aspect ratio. It would be nice to have a control that provided this functionality directly. Try creating a new PhotoBox class based on the Windows Forms Pic- tureBox control that adds a new SizeMode setting called ScaleImage to the control. When set to this value, this new control should display the entire image with the proper aspect ratio within the control, just as we have done throughout the book. You can replace the existing Picture- Box.SizeMode property using a new set of enumeration values by defin- ing the property in the following manner. You will also need to override the OnPaint and OnResize methods to properly draw an image within the new control. private PhotoBoxSizeMode _sizeMode; public new PhotoBoxSizeMode SizeMode { get { return _sizeMode; } set { _sizeMode = value; } } Use your new control in place of the PictureBox control in the Slide- ShowForm window. My implementation of this control is available on the book’s web site. Also included on the site are the instructions for making this new control, referred to as a custom control, available in the Toolbox window of Visual Studio .NET. 18.3 DRAG AND DROP Continuing with our whirlwind tour of topics, let’s take a quick look at drag and drop. This refers to dragging an object from one location to another, and can occur within an application or between applications. Typically, a drag and drop operation is begun by clicking an object with the mouse pointer, holding down the mouse button while moving, or dragging, the object to a new location; and dropping the object at the new location by releasing the mouse button. This topic can get fairly complicated, so we will show a rather basic example sup- porting the following types of drag and drop operations. • Dragging a file from the Windows file system into a PhotoAlbum in a Main- Form window. DRAG AND DROP 619 • Dragging a photograph file from the MainForm window to an external Win- dows location. • Dragging the photograph caption from the MainForm window to a text editor. • Dragging a photograph file from one PhotoAlbum to another within the MyPhotos MDI application. The Windows Forms Control class provides direct support for drag and drop oper- ations. The following table summarizes these members. At a high level, a drag and drop operation performs the following steps. These steps are illustrated by the code in the subsequent sections. Note that the source and target of the operation may be within the same application or in separate applications. 1 A source control initiates drag and drop, typically within a MouseDown event handler, using the DoDragDrop method. One or more data objects and associ- ated formats are provided as part of invoking this method. 2 The user drags the object to a target control that has its AllowDrop property set to true. 3 As the mouse enters the target control, the DragEnter event occurs to permit the target to identify whether the data can be recognized by this control. This permits the operating system to display an appropriate mouse cursor for the user. 4 If so, then the DragOver event occurs as the user moves the drag and drop object within the control. 5 If the object is dragged out of the control, the DragLeave event occurs. 6 If the user releases the object within the target control, then the DragDrop event occurs to permit the control to receive the data. 7 The result of the operation is returned by the DoDragDrop method in the origi- nal source control. Members of the Control class related to drag and drop Public Properties AllowDrop Gets or sets whether the control will permit drag and drop operations within its boundaries. The default is false. Public Methods DoDragDrop Initiates a drag and drop operation from within this control. Typically, this is called from a MouseDown event handler. Public Events DragDrop Occurs when the user completes a drag and drop operation within this control. DragEnter Occurs when an object is dragged into the control’s boundaries. DragLeave Occurs when an object formerly dragged into the control is dragged out of the control’s boundaries. DragOver Occurs when an object within the control is moved within the control’s boundaries. 620 CHAPTER 18 ODDS AND ENDS .NET We will divide our example into two sections. First, we will begin a drag and drop operation from within the PictureBox control of our MainForm class. Next, we will receive external drag and drop operations within this same control. 18.3.1 I NITIATING DRAG AND DROP The key to beginning a drag and drop operation is the DoDragDrop method. This method defines the data for the operation and the kind of operation permitted. public DragDropEffects DoDragDrop(object data, DragDropEffects allowedEffects); While the data parameter can be any data, the DataObject class provides a stan- dard mechanism for safely transferring data between applications. The DragDrop- Effects enumeration permits different types of drag and drop operations to be supported. For example, the Move, Copy, and Link values permit an object to be moved, copied, or linked from the original data source to the drop target. The DoDragDrop method does not return until the drag and drop operation is completed. The return value indicates what effect was performed by the operation. The QueryContinueDrag event in the Control class can be used to keep tabs on the operation. This event occurs periodically during drag and drop and can be used to cancel the operation or to modify the application window as required. In our application, we will simply begin the operation and let the .NET Frame- work take care of the rest. We will provide two types of data formats using the DataObject class. The first will be the FileDrop format recognized by the Win- dows file system and applications such as Microsoft Paint. The second will be the Text format recognized by most word processors. The following table details the changes required. Set the version number of the MyPhotos application to 18.3. BEGIN A DRAG AND DROP OPERATION Action Result 1 Locate the MouseDown event handler for the Panel control in the MainForm.cs code window. private void pnlPhoto_MouseDown (object sender, System.Windows.Forms.MouseEventArgs e) { 2 If the Ctrl key is not held down, then retrieve the current photograph for the album. if (ctrlKeyHeld) { . . . } else { // Initiate drag and drop for this image Photograph photo = _album.CurrentPhoto; DRAG AND DROP 621 This code begins a drag and drop operation that can be received by any other applica- tion running on the computer. Other applications look at the provided data formats to identify whether they can accept the dragged data. We will look at how to do this in Windows Forms in a moment. Of course, for applications that can receive multiple formats, the result they receive depends on which format they prefer. Most word processing applications look for the Text format first, and will therefore receive the Caption property of our photo, rather than the associated file object. Compile and run the application. Display an album and click on the image. Hold the mouse and drag it to a new location to perform a drag and drop operation. Figure 18.3 shows the result of dragging one of our favorite images from the MyPhotos application into a Microsoft Paint application. The Paint application opens the given file and displays a copy of the image in its main window. Also try dragging an image into WordPad or some other word processor to see how the caption string appears. 3 If this Photograph is found, create a FileDrop data format for dragging the photograph to a new location. How-to a. Construct a DataObject instance to hold the data for- mats. b. Construct a string array to hold the associated file. c. Associate the string array with the FileDrop format for the data. if (photo != null) { // Create object for encapsulating data DataObject data = new DataObject(); // Construct string array for FileDrop string[] fileArray = new string[1]; fileArray[0] = photo.FileName; data.SetData(DataFormats.FileDrop, fileArray); Note: The DataFormats class encapsulates vari- ous data formats that can be used by drag and drop operations. The FileDrop format used here requires a string array as the data type. This per- mits multiple files to be provided at once. 4 Also assign a Text format using the Caption property of the photograph as the associated data. // Use the caption for the text format data.SetData(DataFormats.Text, photo.Caption); 5 Call the DoDragDrop method with the constructed data object to initiate a drag and drop Copy operation. // Initiate drag and drop pnlPhoto.DoDragDrop(data, DragDropEffects.Copy); } } } BEGIN A DRAG AND DROP OPERATION (continued) Action Result 622 CHAPTER 18 ODDS AND ENDS .NET This completes our example for initiating a drag and drop operation. The next topic is to handle drag and drop operations within the MainForm window. 18.3.2 R ECEIVING DRAG AND DROP Regardless of where a drag and drop operation originates, an application can elect to handle the incoming data. The DragEnter and DragDrop events are used to receive such operations. Event handlers for both of these events receive a DragEventArgs object as their event parameter. A summary of this object appears in .NET Table 18.4. Figure 18.3 The FileDrop format used here to drag an image into Microsoft Paint is a com- mon method for transferring files between applications. DRAG AND DROP 623 For our example, we will recognize the FileDrop format in the MainForm window to receive files dragged from the file system or from other MainForm windows. The steps required are detailed in the following table: .NET Table 18.4 DragEventArgs class The DragEventArgs class represents the event arguments required for drag and drop events, namely the DragEnter, DragOver, and DragDrop events in the Control class. This class is part of the Sys- tem.Windows.Forms namespace, and inherits from the System.EventArgs class. Public Properties AllowedEffect Gets which drag and drop operations are permitted by the source of the drag event. Data Gets the IDataObject interface that holds the data and data formats associated with the event. Effect Gets or sets the DragDropEffects enumeration values indicating which drag and drop operations are permitted in the target of the drag event. KeyState Gets the current state of the Shift, Ctrl, and Alt keyboard keys. X Gets the x-coordinate of the current mouse pointer position. Y Gets the y-coordinate of the current mouse pointer position. HANDLE DRAG AND DROP IN THE MAINFORM WINDOW Action Result 1 In the MainForm.cs [Design] window, set the AllowDrop property on the Panel control to true. Drop operations are now permitted in the panel control. 2 Add a DragEnter event handler for the panel. private void pnlPhoto_DragEnter (object sender, System.Windows.Forms.DragEventArgs e) { 3 If the data associated with the event supports the FileDrop data format, then indicate that this control will support the Copy drag and drop effect. How-to Use the GetDataPresent method from the IDataObject interface. if (e.Data.GetDataPresent( DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy; 624 CHAPTER 18 ODDS AND ENDS .NET This completes our handling of drag and drop. Compile and run the program to see this in action. Display two different albums in separate MainForm windows. You should be able to perform the following drag and drop operations to obtain the described results: • Find a new image file in Windows Explorer. Drag this file into one of the album windows. The image is added to the album and displayed in the window. • Find an image file in Windows Explorer that is already in an album. Drag this file into the album. The existing Photograph object is displayed in the window. 4 Otherwise, indicate that the current drag and drop data is not accepted by this control. else e.Effect = DragDropEffects.None; } 5 Add a DragDrop event handler for the panel. private void pnlPhoto_DragDrop (object sender, System.Windows.Forms.DragEventArgs e) { 6 In this handler: a. Retrieve the data in FileDrop for- mat associated with the event. b. Convert this data to an Array instance. c. For each object in the array, con- vert the object to a string. object obj = e.Data.GetData( DataFormats.FileDrop); Array files = obj as Array; int index = -1; foreach (object o in files) { string s = o as string; 7 If a string is found, then: a. Create a new Photograph object using this string. b. See if the Photograph is already in the current album. c. If not, then add the new photo to the album. Note: Recall that the Photograph object will simply display a bad image bitmap if an invalid or non- image file name is provided. if (s != null) { Photograph photo = new Photograph(s); // Add the file (if not present) index = _album.IndexOf(photo); if (index < 0) { index = _album.Add(photo); _bAlbumChanged = true; } } } 8 If a Photograph was found in the foreach loop, then a. Adjust the current album position to the discovered index. b. Invalidate the form to redraw the window. if (index >= 0) { // Show the last image added _album.CurrentPosition = index; Invalidate(); } } HANDLE DRAG AND DROP IN THE MAINFORM WINDOW (continued) Action Result ACTIVEX CONTROLS 625 • Highlight a set of files in Windows Explorer. Drag these files into one of the album windows. Each file is added to the window if not already present. The last file added is displayed in the window. • Click on an image displayed in one album window and drag it to a second album window. The image is added to the second album, or displayed if it is already present. This completes our drag and drop example. We should also mention that the List- View and TreeView classes support per-item dragging via the ItemDrag event. The ItemDrag event occurs when the user begins dragging an item in the list or tree. Typically, the event handler for the ItemDrag event calls the DoDragDrop method as we did in this section, with the object associated with a specific list item or tree node as the source of the operation. For example, we could modify our MyAlbumEx- plorer interface to permit photographs to be reordered within the ListView control, or dragged into a new album in the TreeView control. 18.4 ACTIVEX CONTROLS Our final section will look at how to include an ActiveX control, more specifically the Microsoft Web Browser control, within a Windows Forms application. We will avoid a detailed discussion of ActiveX in general and the Web Browser control in particular, and instead allow the example to speak for itself. Our example will host a browser control within an About Box dialog for our MyPhotos application. This may seem slightly unorthodox, but should create an inter- esting example while still presenting the topic at hand. The foundation of ActiveX support in Windows Forms is the AxHost control. This abstract class is, quite simply, a control that hosts, or displays, an ActiveX control as a full-featured Windows Forms control. The class is based on the Windows Forms Control class so that the standard properties, methods, and events we have discussed throughout the book are available in hosted controls. The .NET framework provides an ActiveX Control Importer tool to generate an AxHost interface for a specific ActiveX control. We will discuss this tool in a moment. In our application, we will create an AboutBox form to display information about the application. As shown in figure 18.4, this Form will include a LinkLabel object that will link to the web site for this book. Figure 18.4 This form uses a Label control to display the application Icon, and LinkLabel controls to ini- tiate user actions. [...]... you may need to replace “c:\winnt” in this command with the appropriate Windows directory The two generated files work together to present the ActiveX control as a Windows Forms control in the NET environment The first file AxShDocVw.dll, is named by prepending “Ax” to the given source file name This file encapsulates the Windows Forms proxy class for the control, derived from the AxHost class Each object... the Microsoft Visual Studio NET folder, under the Visual Studio NET Tools heading 2 Create a suitable directory for holding the generated wrapper class cd Windows Forms\ Projects mkdir WebBrowser Note: This example uses the directory “C: \Windows Forms\ Projects\WebBrowser” for this purpose You should use an appropriate directory for your application 3 Change the current directory to be this new directory... Version ver = new Version(Application.ProductVersion); dlg.AboutText = String.Format("MyPhotos (MDI) " + "Application, Version {0:#}.{1:#} " + "\nSample for / "Windows Forms " + "Programming with C#\"\nby " + "Erik Brown \nCopyright (C) 2001 " + "Manning Publications Co.", ver.Major, ver.Minor); dlg.Owner = this; dlg.Icon = this.Icon; How-to a Set IsMdiApplication to true b Set the AboutText property... displayed This completes our example wrapping the Web Browser ActiveX control as a Windows Forms control It also completes this chapter as well as the book In keeping with tradition, we provide a final recap of the topics covered in this chapter 18.5 RECAP This chapter presented an overview of various topics in Windows Forms application development Each topic was discussed very briefly, and we demonstrated... that extended the MyPhotos MDI application built in chapter 16 The specific topics covered included printing from an application, using Windows Forms timers, dragging and dropping objects into and out of an application, and hosting an ActiveX control within a Windows Forms program On the final topic, we illustrated this feature by embedding a Web Browser control within an AboutBox form displayed by our... namespaces, as well as class hierarchy charts for the Windows Forms namespace Good luck with your programming endeavors May your code always compile and applications never fail RECAP 635 A P P E N D I X A C# primer A.1 A.2 A.3 A.4 C# programs 638 Types 639 Language elements 654 Special features 667 This appendix provides an introduction and reference to the C# programming language If you are looking for a... to implement these types, and references to other assemblies While not strictly required, an assembly is normally a single file in a file system For example, the System .Windows. Forms. dll file is the assembly for the System .Windows. Forms namespace There are two kinds of assemblies: Applications and libraries An application is an assembly that has a main entry point and usually has a “.exe” extension... application The Windows Forms ActiveX Control Importer program is called “aximp” and is available as part of the Visual Studio NET product This program is run on the command line and accepts an ActiveX control library C:\> aximp source-file The source-file here is the DLL or OCX file containing the ActiveX control For our purposes, the Web Browser control is located in the file shdocvw.dll in the Windows “system32”... Look up the WebBrowser Control index entry in the online documentation provided with Visual Studio NET for more information on this class private void linkWebSite_LinkClicked (object sender, System .Windows. Forms LinkLabelLinkClickedEventArgs e) { if (browser != null) { // Shut down existing browser pnlWebSite.Visible = false; browser.Dispose(); browser = null; // Reset dialog settings linkWebSite.Text... Browser ActiveX control In this section we will implement the AboutBox form to work as described earlier The following table begins this process by describing the changes required for our standard Windows Forms controls HANDLE THE STANDARD CONTROLS Action Result 1 In the AboutBox.cs code window, create two constants for the two types of icons in our image list protected const int SDI_ICON = 0; protected . ActiveX support in Windows Forms is the AxHost control. This abstract class is, quite simply, a control that hosts, or displays, an ActiveX control as a full-featured Windows Forms control. The. control as a Windows Forms control in the .NET environment. The first file AxShDocVw.dll, is named by prepending “Ax” to the given source file name. This file encapsulates the Windows Forms proxy. directory for holding the generated wrapper class. cd Windows Forms Projects mkdir WebBrowser Note: This example uses the directory “C: Windows Forms ProjectsWebBrowser” for this purpose. You