通过上一篇的学习,已经可以实现跨窗口的拖拽,而且可以在像explorer那样显示图标。
但是还有两个问题。
1. 并不是所有的窗口都支持以explorer的模式显示图标。
比如当你拖拽一个桌面图标到VS2008的窗口,鼠标显示:
这是由于目标窗口(Target)不支持造成的Win32新的拖拽特性造成的。
怎么解决?
为一个办法就是在“拖”(drag)的时候不使用Win32的图标功能,自己动手丰衣足食。
WPF提供了PreviewGiveFeedback和GiveFeedback事件。
ContentElement..::.PreviewGiveFeedback
这个事件在整个拖拽过程中持续发生,用于拖拽的源程序(Source App)可以控制拖拽时的鼠标指针的外观。
下面的代码是就是在创建一个Popup对象,在鼠标拖动的时候Popup的位置始终在鼠标指针偏右下3个像素的位置。避免Popup窗体挡住鼠标指针,无法实现拖拽操作。
void myControl_MouseMove(object sender, MouseEventArgs e)
{
dragPreviewRect = new Rectangle();
dragPreview.Child = dragPreviewRect;
dragPreview.Height = myControl.Height;
dragPreview.Width = myControl.Width;
dragPreviewRect.Fill=new VisualBrush(myControl);
myControl.PreviewGiveFeedback += new GiveFeedbackEventHandler(myControl_PreviewGiveFeedback);
DragDrop.DoDragDrop(myControl, DragDropEffects.Copy,data)
myControl.PreviewGiveFeedback -= new GiveFeedbackEventHandler(myControl_PreviewGiveFeedback);
}
Popup dragPreview = new Popup();
Rectangle dragPreviewRect;
void myControl_PreviewGiveFeedback(object sender, GiveFeedbackEventArgs e)
{
Point p1 = MouseHelper.GetCursorPos();
p1.Offset(3, 3);
dragPreview.HorizontalOffset = p1.X;
dragPreview.VerticalOffset = p1.Y;
dragPreview.IsOpen = true;
e.Handled = true;
}
第二个问题是:
2.如何控制Drop后的行为
我们的程序可以自己接收其他程序的拖拽,但不能让任何程序都接受我的程序的拖放。比如,如果我将我程序中的一个图片拖拽到窗口外面,窗口外可能是桌面,也可能是任意其他的程序。当Drop时,希望在鼠标位置打开一个窗口浏览图片。
不能期望其他程序响应Drop事件,只能自己控制。
其实方法很简单,就是把你要做的事情放在DoDragDrop()方法的后面就可以了。
void myControl_MouseMove(object sender, MouseEventArgs e)
{
DragDrop.DoDragDrop(myControl, DragDropEffects.Copy,data)
Window2 w = new Window2();
Point p1 = MouseHelper.GetCursorPos();
w.Top = p1.Y;
w.Left = p1.X;
w.Show();
}
就这么简单。注意:不能使用 p1 = e.GetPosition(this)的方法
获得鼠标位置。因为这样获得的鼠标位置不准确。