I have a program with two WPF treeviews that allow dragging and dropping between the two. The problem is, it can be annoying to open / close items on the treeviews because moving the mouse just one pixel while holding the left mouse button triggers the drag / drop functionality. Is there some way to specify how far the mouse should move before it's considered a drag / drop?
9
votes
3 Answers
19
votes
There's a system parameter for this. If you have
Point down = {where mouse down event happened}
Point current = {position in the MouseMove eventargs}
then the mouse has moved the minimum drag distance if
Math.Abs(current.X - down.X) >= SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(current.Y - down.Y) >= SystemParameters.MinimumVerticalDragDistance
1
votes
1
votes
Following this article for Drag and Drop implementation, you would have to handle 2 mouse events in order to delay the dragging until the mouse has moved a certain distance. First, add a handler for PreviewMouseDown which stores the initial mouse position relative to your control. Don't use the MouseDown event because it is a bubbling event and may have been handled by a child control before reaching your control.
public class DraggableControl : UserControl
{
private Point? _initialMousePosition;
public DraggableControl()
{
PreviewMouseDown += OnPreviewMouseDown;
}
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e) {
_initialMousePosition = e.GetPosition(this);
}
Additionally, handle MouseMove to check the moved distance and eventually initiate the drag operation:
...
public DraggableControl()
{
...
MouseMove += OnMouseMove;
}
...
private void OnMouseMove(object sender, MouseEventArgs e)
{
// Calculate distance between inital and updated mouse position
var movedDistance = (_initialMousePosition - e.GetPosition(this)).Length;
if (movedDistance > yourThreshold)
{
DragDrop.DoDragDrop(...);
}
}
}