Search code examples
c#.netwpfdrag-and-droptreeview

Scrolling while dragging and dropping (WPF)


Okay guys, I have been scratching my head like mad over this issue and have spent a good few hours trying to research how it works but I am yet to find an answer, if you wish to see any of my SRC feel free to ask about it and I will see if I can help.

Basically the issue I am having is that I have a TreeView of folders in my application i.e.:

Catalog

  Brands
    Nike
    Adidas
    Lactose

  Styles
    Sandles
    Trainers
    Boots

The issue that I am trying to fix is that when I drag a folder around (This is handled in my DragDropManager class), I am unable to scroll up or down(simply displays a lovely stop sign). I am also unable to find a scroller actually within the TreeView, so I am unsure how it is being generated (This is not my own software, I have recently started working for a company so I am not familiar with the code and no one else seems to know.)

This is a problem if I want to move something from the very top to the very bottom.

The scrolling works fine on its own without the dragging being done.

If anyone wishes to see any part of my code feel free to ask as I am unsure what to actually show you guys.

I have read through a good few articles and am just left scratching my head.


Solution

  • I have created an attached property for achieving this behavior, have a look at my post here -

    Attached Behavior for auto scrolling containers while doing Drag & Drop

    Main logic is something like this -

    private static void OnContainerPreviewDragOver(object sender, DragEventArgs e)
    {
        FrameworkElement container = sender as FrameworkElement;
    
        if (container == null) { return; }
    
        ScrollViewer scrollViewer = GetFirstVisualChild<ScrollViewer>(container);
    
        if (scrollViewer == null) { return; }
    
        double tolerance = 60;
        double verticalPos = e.GetPosition(container).Y;
        double offset = 20;
    
        if (verticalPos < tolerance) // Top of visible list? 
        {
            //Scroll up
            scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - offset);
        }
        else if (verticalPos > container.ActualHeight - tolerance) //Bottom of visible list? 
        {
            //Scroll down
            scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset);     
        }
    }
    

    Similar questions on SO (although they are mostly for ListBox/ListView but should work for TreeView too) -

    WPF Listbox auto scroll while dragging

    WPF ListView Databound Drag/Drop Auto Scroll

    WPF Drag-to-scroll doesn't work correctly