Попробовав кучу вещей, я думаю, что нашел способ сделать это. События DragOver
и Drop
отправляют вам параметр DragEventArgs
. Вы используете это, чтобы сделать хит-тестирование. Если вы попали в цель, вы вряд ли попадете в нужный предмет. Скорее, вы столкнетесь с чем-то, что является частью шаблона элемента. Чтобы добраться до интересующих вас элементов TreeView, вы можете попробовать пройтись по визуальному дереву.
В этом примере 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 Вы можете также рассмотреть возможность изменения какого-либо значения в классах данных Bound (например, наличие свойства IsHovering
, которое может выделить элемент посредством привязки данных)