2

I need a control to call DragMove() for a Window on MouseLeftButton down, but still function when clicked.

If DragMove() is called, Click and MouseLeftButtonUp are not ever fired because DragMove() is a blocking call until they release the mouse button.

Does anyone know a workaround to make this work?

I have tried this hack based on Thread.Sleep which allows a click to work if it's quicker than 100 milliseconds, but it does not work reliably for users:

                ThreadPool.QueueUserWorkItem(_ =>
                    {
                        Thread.Sleep(100);

                        Dispatcher.BeginInvoke((Action)
                            delegate
                            {
                                if (Mouse.LeftButton == MouseButtonState.Pressed)
                                {
                                    window.DragMove();
                                }
                            });
                    });

EDIT: Well this hack worked...

                window.DragMove();
                RaiseEvent(new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left) 
                    { 
                        RoutedEvent = MouseLeftButtonUpEvent 
                    });

Anyone have a better one?

jonathanpeppers
  • 26,115
  • 21
  • 99
  • 182

2 Answers2

2

I believe my edit above is the best solution.

jonathanpeppers
  • 26,115
  • 21
  • 99
  • 182
1

If you want both behaviors then you will have to trap both the mouse down and mouse move events. In the mouse down you save the current mouse location:

StartPosition = event.GetPosition(ui_element);

Then in the mouse move you only start a drag if the mouse button is still down and the mouse has moved enough:

        if (e.LeftButton == MouseButtonState.Pressed) {
        Point position = e.GetPosition(Scope);
        if (Math.Abs(position.X - StartPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
            Math.Abs(position.Y - StartPoint.Y) > SystemParameters.MinimumVerticalDragDistance) {
            StartDrag(e);
        }
    }

The SystemParameters object defines the Windows' idea of what a move is.

James Keesey
  • 1,218
  • 9
  • 13
  • What does the StartDrag method do? Are you just setting the Left and Top properties? I would think that would flicker horribly on XP. – jonathanpeppers Dec 17 '09 at 14:02
  • The StartDrag() is just a method on the object that does the drag/drop handling that I do. I replace it with whatever I need at the time, in your case your would call DragMove(). This was stripped out of a Drap/Drop helper class which does more. – James Keesey Dec 17 '09 at 14:29
  • Then your example doesn't work. DragMove() blocks MouseLeftButtonUp from being fired unless you use one of my hacks above, and the 2nd is working beautifully so far--it is just rather ugly. – jonathanpeppers Dec 17 '09 at 15:03