renmin  
常常被别人以为是高手

Technorati 标签: WPF,DragDrop

 

 

通过上一篇的学习,已经可以实现跨窗口的拖拽,而且可以在像explorer那样显示图标。

但是还有两个问题。

1. 并不是所有的窗口都支持以explorer的模式显示图标。

比如当你拖拽一个桌面图标到VS2008的窗口,鼠标显示:

image 或者image

 

 

这是由于目标窗口(Target)不支持造成的Win32新的拖拽特性造成的。

怎么解决?

为一个办法就是在“拖”(drag)的时候不使用Win32的图标功能,自己动手丰衣足食。

WPF提供了PreviewGiveFeedback和GiveFeedback事件。

  • UIElement..::.GiveFeedback

  • UIElement..::.PreviewGiveFeedback

  • ContentElement..::.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)的方法

    获得鼠标位置。因为这样获得的鼠标位置不准确。

  • posted on 2009-06-05 14:46    阅读(2358)  评论(2编辑  收藏  举报