Drag & Drop in WPF TreeView on scroll bar

we use the MVVM template in our application and in the window, we have two TreeView that allow you to drag items from the first and drop them onto the second tree. To avoid the code, we use the behavior to bind the drag and drop to the ViewModel.

The behavior is implemented to a large extent as this example and works like a charm with one error.

A script is a tree that is larger than the window displaying it, so it has a vertical scroll bar. When an item is selected and the user wants to scroll, the program starts dragging (which prevents the actual scrolling and, therefore, not what we want).

This is not surprising since the scroll bar is contained in the TreeView control. But I can’t determine safely if the mouse is above the scrollbar or not.

TreeViewItems represented by themes using Borders, Panels, etc., so a simple InputHitTest not as simple as you might think.

Has anyone already faced the same problem?

If more coverage of the problem code is required, I can insert some lines from .xaml.


Edit

Including the Nikolays link, I solved the problem using the IsMouseOverScrollbar method, if someone has this problem in the future, the code above should be changed as follows:

 private static void PreviewMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton != MouseButtonState.Pressed || startPoint == null) return; if (!HasMouseMovedFarEnough(e)) return; if (IsMouseOverScrollbar(sender, e.GetPosition(sender as IInputElement))) { startPoint = null; return; } var dependencyObject = (FrameworkElement)sender; var dataContext = dependencyObject.GetValue(FrameworkElement.DataContextProperty); var dragSource = GetDragSource(dependencyObject); if (dragSource.GetDragEffects(dataContext) == DragDropEffects.None) return; DragDrop.DoDragDrop( dependencyObject, dragSource.GetData(dataContext), dragSource.GetDragEffects(dataContext)); } private static bool IsMouseOverScrollbar(object sender, Point mousePosition) { if (sender is Visual) { HitTestResult hit = VisualTreeHelper.HitTest(sender as Visual, mousePosition); if (hit == null) return false; DependencyObject dObj = hit.VisualHit; while(dObj != null) { if (dObj is ScrollBar) return true; if ((dObj is Visual) || (dObj is Visual3D)) dObj = VisualTreeHelper.GetParent(dObj); else dObj = LogicalTreeHelper.GetParent(dObj); } } return false; } 
+8
c # wpf drag-and-drop behavior treeview
source share
2 answers

Take a look at this drag and drop implementation for ListView by Josh Smith . It has code to deal with scrollbars and some other non-obvious DnD issues (such as drag treshold, exact mouse coordinates, etc.). This behavior can be easily adopted for working with TreeViews.

+4
source share

I had the same problem. I solved this by placing the TreeView inside a ScrollViewer.

 <ScrollViewer Grid.Column="0"> <TreeView BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseMove="DeviceTree_OnMouseMove" PreviewMouseLeftButtonDown="DeviceTree_OnPreviewMouseLeftButtonDown" Name="DeviceTree" ItemsSource="{Binding Devices}"/> </ScrollViewer> 
0
source share

All Articles