我正在使用一个装饰来显示被拖动元素的'幽灵'......
var adornerLayer = AdornerLayer.GetAdornerLayer(topLevelGrid);
dragAdorner = new DragAdorner(topLevelGrid, itemToDrag);
adornerLayer.Add(dragAdorner);
dragAdorner.UpdatePosition(e.GetPosition(topLevelGrid));
DragDrop.DoDragDrop(sourceItems, viewModel, DragDropEffects.Move);
adornerLayer.Remove(dragAdorner);
itemToDrag = null;
...但我找不到一种很好的方法来在拖动过程中更新装饰者的位置。我最接近的是在顶级网格上设置AllowDrop="true"
并给它一个DragOver处理程序......
private void TopLevelGrid_OnDragOver(object sender, DragEventArgs e)
{
dragAdorner.UpdatePosition(e.GetPosition(topLevelGrid));
}
但这意味着我没有得到关于光标的正确DragDropEffects
反馈,即它总是显示DragDropEffects.Move
光标而不是DragDropEffects.None
,直到我实际下降目标
有谁知道更新装饰位置的更好方法?
答案 0 :(得分:6)
来自Bea Stollnitz的this(不幸的是仅作为缓存版本提供)相当古老的博客文章,它几乎涵盖了您的问题。它有一个很好的拖放实现,一个装饰显示“鬼影”。
基本上拖放WPF是一个非常复杂的过程 - 如果你想要一些自定义的DragAdorners - 涉及添加一堆附加的依赖属性来处理所涉及的所有事件的设置,特别是以不同的方式显示adorner不会干扰掉线代码。
Bea的代码通过在实际拖放操作之前设置一个帮助类来设置拥有Window
的{{1}}事件处理程序和DragOver
,这样就可以控制所有在实际拖动源和放置目标之间移动。
答案 1 :(得分:3)
所以,仔细观察Bea's code redoced指的是......
我仍然在顶级网格上设置AllowDrop="true"
并给它一个DragOver处理程序,我可以在其中更新装配器位置,但我也在这里将DragDropEffects设置为None。然后我只需要向实际的放置目标添加一个DragOver处理程序,以便更新装配器位置......并确保设置e.Handled = true
,以便顶级网格的处理程序不仅将效果设置回无当我超过掉落目标时......
private void TopLevelGrid_OnDragOver(object sender, DragEventArgs e)
{
UpdateDragAdornerPosition(e.GetPosition(topLevelGrid));
e.Effects = DragDropEffects.None;
e.Handled = true;
}
private void DropTarget_OnDragOver(object sender, DragEventArgs e)
{
UpdateDragAdornerPosition(e.GetPosition(topLevelGrid));
e.Handled = true;
}
答案 2 :(得分:0)
我知道这是一个老问题,但是最近我问了同样的事情,然后不得不自己回答。我通过p / invoke使用hooks来获取本机窗口消息,然后再通过拖放操作消耗它们。这使我即使在拖放过程中也可以跟踪鼠标,而不必在我不希望的位置设置AllowDrop。
要获得完整答案(包括我使用的大多数代码),请查看我的问题:
WPF - Track mouse during Drag & Drop while AllowDrop = False