Customizing Drag and Drop


A large part of avoiding undue development work is our dependence on the underlying drag-and-drop infrastructure to provide a consistent experience by default, something it does well. Although they are uncommon, some situations call for your applications to support a more specialized experience. The drag-and-drop infrastructure supports this by allowing you to customize the types of mouse cursors used for drag and drop. It also lets you control when a drag-and-drop operation completes and in what state it does so.

Using Custom Cursors

Some applications may have a special need for cursors other than the default systemprovided drag-and-drop cursors. Such applications might include those that promote a highly stylized look and feel or those that, for contextual reasons, need to display dragging and dropping within a document in a different way from dragging and dropping across documents. In any case, Windows Forms provides the GiveFeedback event, which you handle within the scope of your drag operation. GiveFeedback is fired to the control or form on which DoDragDrop was called and allows you to detect the current drag-and-drop effect and change the cursor as appropriate:

// MainForm.cs using System.IO; // For MemoryStream ... partial class MainForm : Form {   static Cursor CustomMoveCursor =     new Cursor(new MemoryStream(Properties.Resources.CustomMove));   static Cursor CustomCopyCursor =     new Cursor(new MemoryStream(Properties.Resources.CustomCopy));   void dragSourceLabel_GiveFeedback(     object sender, GiveFeedbackEventArgs e) {     // Is a drag and drop move in effect?     if (e.Effect == DragDropEffects.Move) {       // Use the custom move cursor       e.UseDefaultCursors = false;       this.Cursor = MainForm.CustomMoveCursor;       return;     }     // Is a drag and drop copy in effect?     if (e.Effect == DragDropEffects.Copy) {       // Use the custom copy cursor       e.UseDefaultCursors = false;       this.Cursor = MainForm.CustomCopyCursor;       return;     }     // Use default cursors for any other drag and drop effect     // e.UseDefaultCursors = true by default   }   ... } 


When you provide a custom cursor, you need to let the underlying drag-and-drop operation know.[3] You do this by setting the UseDefaultCursors property exposed by GiveFeedbackEventArgs to false. If you don't, your cursor change is overridden by the system.

[3] See Chapter 13: Resources for information about adding resources like cursors to your application.

Also, make sure you set your cursor back to the default cursor if a custom cursor isn't required. Otherwise, the last cursor change is retained, incorrectly reporting the current drag-and-drop operation, if any:

// MainForm.cs partial class MainForm : Form {   ...   void dragSourceLabel_MouseDown(object sender, MouseEventArgs e) {     ...     this.Cursor = Cursors.Default;   } }


Figure E.8 shows the effect of this code during a drag-and-drop move operation.

Figure E.8. Using a Custom Drag-and-Drop Move Cursor


Figure E.9 shows the same for a drag-and-drop copy operation.

Figure E.9. Using a Custom Drag-and-Drop Copy Cursor


Being able to change the default drag-and-drop cursors is essential when your drag-and-drop operations need more contextually relevant imagery. However, users are most familiar with the default cursors, so you should have a good reason to provide your own, and to require your users to become familiar with them.

Controlling Drag-and-Drop Completion

Just as you need a good reason to replace the system-provided drag-and-drop cursors with your own custom versions, you need a good reason to alter the default drag-and-drop completion behavior, which is to support dragging within and across applications. However, suppose your application uses highly sensitive data and you need to conform to security policy, which prevents data from being taken outside the application. As part of that policy, you might try to prevent data from being dragged anywhere except within the application.

In this case, you handle the QueryContinueDrag event, which, like GiveFeedback, is fired to the drop source. Handling QueryContinueDrag allows you to check for and, if necessary, cancel the drag-and-drop operation. You implement cancellation by setting the Action property on the QueryContinueDragEventArgs passed to QueryContinueDrag:

// MainForm.cs partial class MainForm : Form {   ...   void dragSourceLabel_QueryContinueDrag(     object sender, QueryContinueDragEventArgs e) {     // Get the current cursor position, relative to the form     Point cursorPosition = this.PointToClient(Cursor.Position);     // Cancel the drag and drop operation if the cursor     // is dragged outside the form     if (!this.ClientRectangle.Contains(cursorPosition)) {       e.Action = DragAction.Cancel;     }   } }


Figure E.10 shows the result of cancellation when the mouse moves beyond the host form.

Figure E.10. A Canceled Drag-and-Drop Operation


The QueryContinueDragEventArgs.Action property that was used to cancel the drag-and-drop operation can be a value determined by the DragAction enumeration:

namespace System.Windows.Forms {   enum DragAction {     Continue = 0, // Continues the drag-and-drop operation (default)     Drop = 1 // Forces the drag data to be dropped     Cancel = 2, // Cancels the drag-and-drop operation   } }


QueryContinueDragEventArgs also provides KeyState information, just as DragEventArgs does, which may be useful when you need more granular information about the state of the drag-and-drop operation before you change the action.




Windows Forms 2.0 Programming
Windows Forms 2.0 Programming (Microsoft .NET Development Series)
ISBN: 0321267966
EAN: 2147483647
Year: 2006
Pages: 216

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net