Drag and drop in TreeView, search for the index into which to remove the deleted item

I have WPF TreeViewwith one level of children. I use HierarchicalDataTemplatefor top-level items, so the child items are tied to a list of backup data.

When I do a drag and drop, I want to find out where new items should appear in the target list. I broke scripts in the following cases:

  • I'm on the empty side of the target TreeView
  • I am at TreeViewItemor near the top levels (the deleted item should go to the end of the list)
  • I am on one of the child elements, in which case the removed element should go either to the front or to the back of the current element, depending on whether I am fending off the upper or lower half of the element.

My question is, how do I know which ones TreeViewItemI'm soaring with? How do I know if this is a type of a parent type or a child type TreeViewItem? (They have different types of data DataContext) Should I do some tricks? How do I know which top-level item belongs to the current child that I'm piling over?

+3
source share
2 answers

, , . DragOver Drop DragEventArgs. , . hittest , , . , -, . TreeViewItems, .

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");
    }

- , , , adorner, Bea Stollnitz. - Bound (, IsHovering, ).

+6

, , , Pieter Breed.

private void Tree_DragOver(object sender, DragEventArgs e) {
TreeViewItem treeViewItem = FindAncestor<TreeViewItem>((DependencyObject)e.OriginalSource);
if (treeViewItem != null) {
    treeViewItem.Background = Brushes.Blue;
}
}   
private void Tree_DragLeave(object sender, DragEventArgs e) {
TreeViewItem treeViewItem = FindAncestor<TreeViewItem>((DependencyObject)e.OriginalSource);
if (treeViewItem != null) {
    treeViewItem.Background = Brushes.White;
}
}
private static T FindAncestor<T>(DependencyObject current) where T : DependencyObject { // Search the VisualTree for specified type
while (current != null) {
    if (current is T) {
        return (T)current;
    }
    current = VisualTreeHelper.GetParent(current);
}
return null;
}
+3

Source: https://habr.com/ru/post/1717772/


All Articles