DoDragDrop 方法的使用

DoDragDrop方法,用于开始对象的拖放操作。

在类库中的定义为:

1 [UIPermissionAttribute(SecurityAction.Demand, Clipboard = UIPermissionClipboard.OwnClipboard)]
2 public DragDropEffects DoDragDrop(
3 Object data,
4 DragDropEffects allowedEffects
5 )

  其中data参数为要拖放的数据,如果拖动操作需要于另一个进程的应用程序相互操作,data代表的数据应该是基本托管类(String,BitMap,或MetaFile),或者是实现 ISerializable 或IDataObject的对象。 allowedEffects参数表示拖放的效果,为一个枚举值(DragDropEffects).返回值也为DragDropEffects枚举值。

  当开始调用DoDragDrop方法拖动一个数据对象时,DoDragDrops在拖放过程中,检测当前光标位置下的控件是不是有效的放置目标。如果当前光标下的控件是有效的放置目标,则GiveFeedBack事件以指定的拖放效果引发。在检测当前位置光标是否为有效的拖放目标时,DoDragDrops方法同时跟踪光标位置,键盘状态和鼠标状态的更改。

   (1)如果用于移出了一个窗口,则引发DragLeave事件。

   (2)如果移入了另外一个控件,则引发该控件的DragEnter事件。

  (3)如果鼠标移动,但是停留在一个控件中,则引发DragOver事件。

  如果检测到更改了键盘或者鼠标状态,则引发拖放源的QueryContinueDrag事件, 并根据事件的QueryContinueDragEventArgs的Action属性值确定继续拖动,放置数据或取消操作。

    (1)如果Action属性指定为Continue,则将引发DragOver事件。

      (2)如果Action属性指定为Drop,则将放置效果返回给源,以便应用程序对数据进行适当的操作;例如,如果是移动操作,则剪切数据。

     (3)如果是DragAction的值为Cancel,则引发DragLeave事件

 

  从csdn上摘抄一段示例代码:

  下面的代码示例演示在两个 ListBox 控件之间的拖放操作。当拖动动作启动时,该示例调用 DoDragDrop 方法。在 MouseDown 事件期间,如果从鼠标位置起鼠标移动的距离大于 SystemInformation..::.DragSize,则启动拖动动作。IndexFromPoint 方法用于确定在 MouseDown 事件期间要拖动的项的索引。

  该示例还演示如何对拖放操作使用自定义光标。该示例要求应用程序目录中存在两个光标文件:3dwarro.cur3dwno.cur,分别用于自定义拖动光标和禁止停放光标。如果选中 UseCustomCursorsCheckCheckBox,则使用自定义光标。自定义光标在 GiveFeedback 事件处理程序中设置。

  键盘状态在右 ListBox 的 DragOver 事件处理程序中计算,以确定基于 Shift、Ctrl、Alt 或 Ctrl+Alt 键的状态将发生哪种拖动操作。放置动作在 ListBox 中发生的位置也在 DragOver 事件期间确定。如果要放置的数据不是 String,则 DragDropEffects 中将把 DragEventArgs.sEffect 设置为 None。最后,停放状态在 DropLocationLabelLabel 中显示。

  要放置的用于右 ListBox 的数据在 DragDrop 事件处理程序中确定,并且在 ListBox 中的适当位置添加该 String 值。如果拖动操作移动到窗体边框的外面,则 QueryContinueDrag 事件处理程序中将取消拖放操作

View Code
  1 using System;
2 using System.Drawing;
3 using System.Windows.Forms;
4
5 namespace Snip_DragNDrop
6 {
7 public class Form1 : System.Windows.Forms.Form
8 {
9 private System.Windows.Forms.ListBox ListDragSource;
10 private System.Windows.Forms.ListBox ListDragTarget;
11 private System.Windows.Forms.CheckBox UseCustomCursorsCheck;
12 private System.Windows.Forms.Label DropLocationLabel;
13
14 private int indexOfItemUnderMouseToDrag;
15 private int indexOfItemUnderMouseToDrop;
16
17 private Rectangle dragBoxFromMouseDown;
18 private Point screenOffset;
19
20 private Cursor MyNoDropCursor;
21 private Cursor MyNormalCursor;
22
23 /// The main entry point for the application.
24 [STAThread]
25 static void Main()
26 {
27 Application.Run(new Form1());
28 }
29
30 public Form1()
31 {
32 this.ListDragSource = new System.Windows.Forms.ListBox();
33 this.ListDragTarget = new System.Windows.Forms.ListBox();
34 this.UseCustomCursorsCheck = new System.Windows.Forms.CheckBox();
35 this.DropLocationLabel = new System.Windows.Forms.Label();
36
37 this.SuspendLayout();
38
39 // ListDragSource
40 this.ListDragSource.Items.AddRange(new object[] {"one", "two", "three", "four",
41 "five", "six", "seven", "eight",
42 "nine", "ten"});
43 this.ListDragSource.Location = new System.Drawing.Point(10, 17);
44 this.ListDragSource.Size = new System.Drawing.Size(120, 225);
45 this.ListDragSource.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseDown);
46 this.ListDragSource.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.ListDragSource_QueryContinueDrag);
47 this.ListDragSource.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseUp);
48 this.ListDragSource.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseMove);
49 this.ListDragSource.GiveFeedback += new System.Windows.Forms.GiveFeedbackEventHandler(this.ListDragSource_GiveFeedback);
50
51 // ListDragTarget
52 this.ListDragTarget.AllowDrop = true;
53 this.ListDragTarget.Location = new System.Drawing.Point(154, 17);
54 this.ListDragTarget.Size = new System.Drawing.Size(120, 225);
55 this.ListDragTarget.DragOver += new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragOver);
56 this.ListDragTarget.DragDrop += new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragDrop);
57 this.ListDragTarget.DragEnter += new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragEnter);
58 this.ListDragTarget.DragLeave += new System.EventHandler(this.ListDragTarget_DragLeave);
59
60 // UseCustomCursorsCheck
61 this.UseCustomCursorsCheck.Location = new System.Drawing.Point(10, 243);
62 this.UseCustomCursorsCheck.Size = new System.Drawing.Size(137, 24);
63 this.UseCustomCursorsCheck.Text = "Use Custom Cursors";
64
65 // DropLocationLabel
66 this.DropLocationLabel.Location = new System.Drawing.Point(154, 245);
67 this.DropLocationLabel.Size = new System.Drawing.Size(137, 24);
68 this.DropLocationLabel.Text = "None";
69
70 // Form1
71 this.ClientSize = new System.Drawing.Size(292, 270);
72 this.Controls.AddRange(new System.Windows.Forms.Control[] {this.ListDragSource,
73 this.ListDragTarget, this.UseCustomCursorsCheck,
74 this.DropLocationLabel});
75 this.Text = "drag-and-drop Example";
76
77 this.ResumeLayout(false);
78
79 }
80
81 private void ListDragSource_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
82 {
83 // Get the index of the item the mouse is below.
84 indexOfItemUnderMouseToDrag = ListDragSource.IndexFromPoint(e.X, e.Y);
85
86 if (indexOfItemUnderMouseToDrag != ListBox.NoMatches) {
87
88 // Remember the point where the mouse down occurred. The DragSize indicates
89 // the size that the mouse can move before a drag event should be started.
90 Size dragSize = SystemInformation.DragSize;
91
92 // Create a rectangle using the DragSize, with the mouse position being
93 // at the center of the rectangle.
94 dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width /2),
95 e.Y - (dragSize.Height /2)), dragSize);
96 } else
97 // Reset the rectangle if the mouse is not over an item in the ListBox.
98 dragBoxFromMouseDown = Rectangle.Empty;
99
100 }
101
102 private void ListDragSource_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
103 // Reset the drag rectangle when the mouse button is raised.
104 dragBoxFromMouseDown = Rectangle.Empty;
105 }
106
107 private void ListDragSource_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
108 {
109
110 if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {
111
112 // If the mouse moves outside the rectangle, start the drag.
113 if (dragBoxFromMouseDown != Rectangle.Empty &&
114 !dragBoxFromMouseDown.Contains(e.X, e.Y)) {
115
116 // Create custom cursors for the drag-and-drop operation.
117 try {
118 MyNormalCursor = new Cursor("3dwarro.cur");
119 MyNoDropCursor = new Cursor("3dwno.cur");
120
121 } catch {
122 // An error occurred while attempting to load the cursors, so use
123 // standard cursors.
124 UseCustomCursorsCheck.Checked = false;
125 }finally {
126
127 // The screenOffset is used to account for any desktop bands
128 // that may be at the top or left side of the screen when
129 // determining when to cancel the drag drop operation.
130 screenOffset = SystemInformation.WorkingArea.Location;
131
132 // Proceed with the drag-and-drop, passing in the list item.
133 DragDropEffects dropEffect = ListDragSource.DoDragDrop(ListDragSource.Items[indexOfItemUnderMouseToDrag], DragDropEffects.All | DragDropEffects.Link);
134
135 // If the drag operation was a move then remove the item.
136 if (dropEffect == DragDropEffects.Move) {
137 ListDragSource.Items.RemoveAt(indexOfItemUnderMouseToDrag);
138
139 // Selects the previous item in the list as long as the list has an item.
140 if (indexOfItemUnderMouseToDrag > 0)
141 ListDragSource.SelectedIndex = indexOfItemUnderMouseToDrag -1;
142
143 else if (ListDragSource.Items.Count > 0)
144 // Selects the first item.
145 ListDragSource.SelectedIndex =0;
146 }
147
148 // Dispose of the cursors since they are no longer needed.
149 if (MyNormalCursor != null)
150 MyNormalCursor.Dispose();
151
152 if (MyNoDropCursor != null)
153 MyNoDropCursor.Dispose();
154 }
155 }
156 }
157 }
158 private void ListDragSource_GiveFeedback(object sender, System.Windows.Forms.GiveFeedbackEventArgs e)
159 {
160 // Use custom cursors if the check box is checked.
161 if (UseCustomCursorsCheck.Checked) {
162
163 // Sets the custom cursor based upon the effect.
164 e.UseDefaultCursors = false;
165 if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move)
166 Cursor.Current = MyNormalCursor;
167 else
168 Cursor.Current = MyNoDropCursor;
169 }
170
171 }
172 private void ListDragTarget_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
173 {
174
175 // Determine whether string data exists in the drop data. If not, then
176 // the drop effect reflects that the drop cannot occur.
177 if (!e.Data.GetDataPresent(typeof(System.String))) {
178
179 e.Effect = DragDropEffects.None;
180 DropLocationLabel.Text = "None - no string data.";
181 return;
182 }
183
184 // Set the effect based upon the KeyState.
185 if ((e.KeyState & (8+32)) == (8+32) &&
186 (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {
187 // KeyState 8 + 32 = CTL + ALT
188
189 // Link drag-and-drop effect.
190 e.Effect = DragDropEffects.Link;
191
192 } else if ((e.KeyState & 32) == 32 &&
193 (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {
194
195 // ALT KeyState for link.
196 e.Effect = DragDropEffects.Link;
197
198 } else if ((e.KeyState & 4) == 4 &&
199 (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) {
200
201 // SHIFT KeyState for move.
202 e.Effect = DragDropEffects.Move;
203
204 } else if ((e.KeyState & 8) == 8 &&
205 (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) {
206
207 // CTL KeyState for copy.
208 e.Effect = DragDropEffects.Copy;
209
210 } else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) {
211
212 // By default, the drop action should be move, if allowed.
213 e.Effect = DragDropEffects.Move;
214
215 } else
216 e.Effect = DragDropEffects.None;
217
218 // Get the index of the item the mouse is below.
219
220 // The mouse locations are relative to the screen, so they must be
221 // converted to client coordinates.
222
223 indexOfItemUnderMouseToDrop =
224 ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(new Point(e.X, e.Y)));
225
226 // Updates the label text.
227 if (indexOfItemUnderMouseToDrop != ListBox.NoMatches){
228
229 DropLocationLabel.Text = "Drops before item #" + (indexOfItemUnderMouseToDrop + 1);
230 } else
231 DropLocationLabel.Text = "Drops at the end.";
232
233 }
234 private void ListDragTarget_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
235 {
236 // Ensure that the list item index is contained in the data.
237 if (e.Data.GetDataPresent(typeof(System.String))) {
238
239 Object item = (object)e.Data.GetData(typeof(System.String));
240
241 // Perform drag-and-drop, depending upon the effect.
242 if (e.Effect == DragDropEffects.Copy ||
243 e.Effect == DragDropEffects.Move) {
244
245 // Insert the item.
246 if (indexOfItemUnderMouseToDrop != ListBox.NoMatches)
247 ListDragTarget.Items.Insert(indexOfItemUnderMouseToDrop, item);
248 else
249 ListDragTarget.Items.Add(item);
250
251 }
252 }
253 // Reset the label text.
254 DropLocationLabel.Text = "None";
255 }
256 private void ListDragSource_QueryContinueDrag(object sender, System.Windows.Forms.QueryContinueDragEventArgs e) {
257 // Cancel the drag if the mouse moves off the form.
258 ListBox lb = sender as ListBox;
259
260 if (lb != null) {
261
262 Form f = lb.FindForm();
263
264 // Cancel the drag if the mouse moves off the form. The screenOffset
265 // takes into account any desktop bands that may be at the top or left
266 // side of the screen.
267 if (((Control.MousePosition.X - screenOffset.X) < f.DesktopBounds.Left) ||
268 ((Control.MousePosition.X - screenOffset.X) > f.DesktopBounds.Right) ||
269 ((Control.MousePosition.Y - screenOffset.Y) < f.DesktopBounds.Top) ||
270 ((Control.MousePosition.Y - screenOffset.Y) > f.DesktopBounds.Bottom)) {
271
272 e.Action = DragAction.Cancel;
273 }
274 }
275 }
276 private void ListDragTarget_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
277 // Reset the label text.
278 DropLocationLabel.Text = "None";
279 }
280 private void ListDragTarget_DragLeave(object sender, System.EventArgs e) {
281 // Reset the label text.
282 DropLocationLabel.Text = "None";
283 }
284 }
285 }

对用这种拖放操作和微软的服务,容器模式的关系,留在以后再学习。


 

 

posted on 2011-12-15 11:16  Tasting  阅读(2923)  评论(0编辑  收藏  举报

导航