非常简单的 WPF 拖放示例, 无需 Win32 调用






4.23/5 (16投票s)
无需 P/Invoke 的拖放示例
引言
我从 Josh Smith 的文章 在 WPF ListView 中拖放项目中学到了如何在 WPF 中实现拖放。Josh 的优秀文章和附带的代码描述了许多与拖放功能相关的 WPF 特性。但是,我觉得大多数时候人们可能只想使用一个普通的、原始的拖放功能,而不需要大多数这些特性。对于这些人来说,这篇文章和相关的代码可能更有用。
除此之外,Josh 使用了 Dan Crevier 开发的 MouseUtilities
类,该类调用了一些 Win32 函数。我通过使用事件的 GetPosition
方法解决了这个问题。因此,应该可以在 Web 浏览器应用程序 (XBAP) 中使用这里提供的功能,没有任何问题。
后续说明 - 08 年 3 月 16 日添加:实际上,这是真的,在部分信任下,无法使用 DragDrop.DoDragDrop()
函数运行 XBAP 应用程序。要查看 XBAP 的拖放实现示例,请查看 为基于浏览器的 WPF 应用程序 (XBAP) 实现拖放操作。此外,对于多选拖放,请参阅 WPF 中的多选拖放。
Using the Code
要使用代码,只需下载它,使用 Visual Studio 2008 打开项目,编译并运行即可。
使用拖放重新排序列表中的项目。
简短代码说明
基本上有三个包含代码的文件
- Shape.cs
- Window1.xaml
- Window.xaml.cs
Shape.cs 包含用于用作 ListView
后面的项目的非常简单对象的定义。每个项目都有一个名称和边数作为属性。
Window1.xaml 包含 XAML,表示一个非常简单的 Window
,其中包含 ListView
控件。ListView
的 ItemsSource
属性设置为指向 Shape
对象集合。
Window1.xaml.cs 包含所有 C# 管道和实际进行拖放的函数
ListView1_PreviewMouseLeftButtonDown
- 启动拖动操作ListView1_Drop
- 完成放置操作
使用 Event Argument GetPosition 函数确定当前鼠标位置
DragEventArgs
和 MouseButtonEventArgs
类都具有以下函数
Point GetPosition(IInputElement)
此函数返回相对于 Visual 元素的当前鼠标位置(作为参数传递给该函数)。由于 DragEventArgs
和 MouseButtonEventArgs
没有定义 GetPosition
函数的公共超类或接口,因此我编写了将 GetPosition
函数作为 委托
的代码,以便能够将其重用于这两个类。以下是返回列表中当前项目 index
的功能
int GetCurrentIndex(GetPositionDelegate getPosition)
{
int index = -1;
for (int i = 0; i < this.ListView1.Items.Count; ++i)
{
ListViewItem item = GetListViewItem(i);
if (this.IsMouseOverTarget(item, getPosition))
{
index = i;
break;
}
}
return index;
}
bool IsMouseOverTarget( Visual target, GetPositionDelegate getPosition)
{
Rect bounds = VisualTreeHelper.GetDescendantBounds( target );
Point mousePos = getPosition((IInputElement) target);
return bounds.Contains( mousePos );
}
GetPositionDelegate
定义为
delegate Point GetPositionDelegate(IInputElement element);
以下是函数 GetCurrentIndex
的调用方式:来自 ListView1_Drop
函数 - 负责放置操作(此函数使用 DragEventArgs
)
void ListView1_Drop(object sender, DragEventArgs e)
{
...
int index = this.GetCurrentIndex(e.GetPosition);
...
}
来自 ListView1_PreviewMouseLeftButtonDown
函数 - 负责启动拖动操作(此函数使用 MouseButtonEventArgs
)
void ListView1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
...
oldIndex = this.GetCurrentIndex(e.GetPosition);
...
}
历史
- 2008 年 3 月 3 日:初始帖子
- 2008 年 3 月 16 日:添加了对其他拖放文章的引用