在尝试了一堆东西之后,我想我已经想出了一个办法来做到这一点。 DragOver
和Drop
事件向您发送DragEventArgs
参数。你用它来做点击测试。如果你击中了,你不可能直接击中你想要的物品。相反,你将会碰到构成项目模板一部分的东西。要访问您感兴趣的TreeViewItems,您可以尝试并沿着Visual Tree走。
在这个例子中的顶层TreeViewItems
被绑定到GroupItem
实例和子节点被绑定到DragItems
实例。 tv
是TreeView元素本身的名称。在这段代码中,假定我会找到它,因为事件处理程序是在这个元素上定义的。
我创建了以下遍历树的代码。
private void FindDropTarget(
out TreeViewItem pGroupingNode,
out TreeViewItem pItemNode,
DragEventArgs pDragEventArgs)
{
pItemNode = null;
pGroupingNode = null;
DependencyObject k = VisualTreeHelper.HitTest(tv, pDragEventArgs.GetPosition(tv)).VisualHit;
while (k != null)
{
if (k is TreeViewItem)
{
TreeViewItem treeNode = k as TreeViewItem;
if (treeNode.DataContext is GroupItem)
{
pGroupingNode = treeNode;
}
else if (treeNode.DataContext is DragItems)
{
pItemNode = treeNode;
}
}
else if (k == tv)
{
Console.WriteLine("Found treeview instance");
return;
}
k = VisualTreeHelper.GetParent(k);
}
}
像这样消耗它。注意检查IsVisible
这是很重要的:
private void tv_DragOver(object sender, DragEventArgs e)
{
TreeViewItem groupingNode, itemNode;
FindDropTarget(out groupingNode, out itemNode, e);
GroupItem groupingData = (groupingNode != null ? groupingNode.DataContext as GroupItem : null);
DragItems dragItem = (itemNode != null && itemNode.IsVisible ? itemNode.DataContext as DragItems : null);
Console.WriteLine("Hovering ...");
Console.WriteLine(
"Grouping Node = {0}, Item Node = {1}",
groupingData != null ? groupingData.Title : "null",
dragItem != null ? dragItem.Id : "null");
}
如果你想给某种要将项目下降视觉指示的,可以考虑使用装饰器就像Bea Stollnitz explains here。你也可以考虑改变Bound数据类的某种价值(比如有一个IsHovering
属性,它可以通过数据绑定高亮显示该物品)