为基于浏览器的 WPF 应用程序 (XBAP) 实现拖放操作






4.71/5 (6投票s)
无需完全信任即可实现简单的拖放操作

引言
在文章“非常简单的 WPF 拖放示例,无需 Win32 调用”中,我曾说过,由于未使用 Win32 调用,生成的代码也应该可以在部分信任下在浏览器中工作。好吧……我错了。事实证明,DragDrop.DoDragDrop(...)
函数会在部分信任下的 XBAP 应用程序中抛出 SecurityException
,因为 DragDrop.DoDragDrop
启动了一个所谓的 OLE 拖放操作。对于大多数应用程序,当我们只拖放 WPF 对象时,不需要 OLE 传输。因此,在本文中,我提供了一个模拟拖放功能的示例,该示例不使用 DragDrop.DoDragDrop
方法,可以在浏览器中运行。
Using the Code
要使用代码,只需解压缩文件,启动项目,编译并运行应用程序。
为了使应用程序在浏览器中工作,我不得不弄清楚两件事:确保光标的图像可见并采用我们想要的样子。两者都在 ListView1.MouseMove
事件的 ListView1_MouseMove
回调中实现。
要使光标可见,我们只需执行
Mouse.SetCursor(Cursors.Hand);
然而,仍然存在一个问题:我希望光标变成一个矩形,但 Cursors
枚举中没有矩形形状。更糟糕的是,您不能在 XBAP 部分信任应用程序中使用位图图像作为光标。为了解决这个问题,我将光标设置为一个半透明矩形,仅在拖放操作期间可见。
<Rectangle
Name="CursorRectangle"
Height="10"
Width="20"
Visibility="Hidden">
<Rectangle.Fill>
<SolidColorBrush Color="Blue"
Opacity="0.35"/>
</Rectangle.Fill>
</Rectangle>
以下代码确保光标矩形不会超出 ListView
控件的边界
Point p = e.GetPosition(ListView1); // get the location of the mouse pointer
// get the boundaries of the ListView control (the cursor should not
// be allowed to go beyond those boundaries
Rect bounds = VisualTreeHelper.GetDescendantBounds(ListView1);
// set the vertical coordinate of the cursor to
// coincide with the current mouse vertical coordinate
// as long as we are still within the boundaries of the
// ListView control
if ( (bounds.Top < p.Y) && (bounds.Bottom > p.Y))
{
Canvas.SetTop(CursorRectangle, p.Y);
}
// set the vertical coordinate of the cursor to
// coincide with the current mouse horizontal coordinate
// as long as we are still within the boundaries of the
// ListView control
if ((bounds.Left < p.X) && (bounds.Right > p.X))
{
Canvas.SetLeft(CursorRectangle, p.X);
}
其余代码与“非常简单的 WPF 拖放示例,无需 Win32 调用”文章中的代码非常相似。
历史
- 2008 年 3 月 16 日:初始发布