在寻找这个问题的解决方案的过程中,一个新的问题出现了。
在 .NET 中使用 Drag'n'Drop 的 WinForms 控件有几个典型的事件和DoDragDrop方法。
但是有几个问题与它们相关。如果我们DoDragDrop
在事件上激活MouseDown
,那么在拖动过程完成之前,我们程序的窗口不会接收鼠标事件,但会接收与拖动过程相关的事件。到目前为止,一切似乎都是合乎逻辑的,但是如果在激活对象的拖动后鼠标没有移动,那么该过程不会立即结束,而是无限期超时,此时鼠标事件不会传输到我们的窗口,它实际上导致了上面链接中问题中描述的问题。
对于TreeView
并且ListView
事实证明有一个开箱即用的解决方案 - 一个事件ItemDrag
,但对于可能成为拖放源的其他控件,没有提供这样的解决方案。
到目前为止,只有一种解决方案浮现在脑海:
在一个事件中
MouseDown
,提出一个关于可能开始拖放的标志,并记住私有表单字段中的潜在拖动对象。通过事件
MouseMove
,检查鼠标按钮的标志和状态,如果满足指定条件,则调用DoDragDrop
参数中的方法,将之前保存的对象作为数据传递给拖动。然后重置标志。
但出于某种原因,在我看来这是一个拐杖,因为根据我们要拖放的内容和位置,代码会有所不同,并且必须为需要此类功能的每个表单复制代码。
实际上问题是,我是否正确理解拖放过程是在操作系统的上下文中执行的,而不是在单个程序中执行的,以确保可以在程序之间拖动对象?如果假设是正确的,那么是否有一种解决方案可以更灵活地解决这些问题,而无需用拐杖制造自行车?如果我的假设不正确,那么在答案中我想看看它是如何工作的。
这个问题是针对 WinAPI 鉴赏家的,但我想在 C# 的上下文中得到一个解决方案。原则上,对我来说,任何适用于 .NET 的解决方案都可以,只要它比已经说明的解决方案更好。
我会合乎逻辑地争论:你没有太多的控件可以接受拖动的对象。我敢肯定他们在1-3的实力形式上。
那么为什么不看看它是如何
ItemDrag
在TreeView
和中实现的ListView
(幸运的是,可以很容易地在 google 上搜索“treeview 源代码”)并通过继承和后续扩展功能在必要的控件中实现您需要的 ItemDrag 事件?ItemDrag
原始类的所有继承人的代码)我会将需要使用 Drag'n'Drop 的控件包装在以下包装器中:
一边这样想。包裹控制..