tags:

views:

263

answers:

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?

A: 

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
What does the StartDrag method do? Are you just setting the Left and Top properties? I would think that would flicker horribly on XP.
Jonathan.Peppers
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
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.
Jonathan.Peppers
I use this all this time but use whatever works for you.
James Keesey
A: 

I believe my edit above is the best solution.

Jonathan.Peppers