What does it mean to "Capture the mouse" in WPF? - wpf

On System.Windows.UIElement there is a CaptureMouse() and a paired ReleaseMouseCapture() method. In this WPF DragDrop sample they call CaptureMouse on MouseDown and release it on MouseUp. The documentation in MSDN is about as useless as it comes - "CaptureMouse -> Captures the mouse."
In my head before trying it I assumed that it somehow locked the mouse inside the UIElement bounds, but that's clearly not the case when I try it. From experimenting, it seems to have something to do with responding to events when the mouse is outside of the UIElement, but not wanting to be a cargo cult programmer I don't want to just use it because the example does, I'd like an authoritative description of what it means.

From Capture and Uncapture the Mouse on MSDN:
When an object captures the mouse, all mouse related events are treated as if the object with mouse capture perform the event, even if the mouse pointer is over another object.
Only the capturing control receives the mouse events until released.
Capturing the mouse is useful for dragging because all the dragging code can exist in the one control, rather than being spread over multiple controls.

When it has captured the mouse, a control will receive mouse events even if the mouse pointer is no longer within its bounding area.
Typically, it's used for:
Drag and drop
Buttons (to handle Mouse Up when you put the mouse down on the button and move the mouse before you release the button)

The Silverlight 2 documentation for it has a more verbose description, I don't know why it isn't a part of the 3.5 documentation page too:
When an object has captured the mouse, that object receives mouse input whether or not the mouse pointer is within its bounding area. The mouse is typically only captured during simulated drag operations.
...
It works the same with WPF, and so the reason it is used with DragDrop, is that is how the
it knows to report back to the control being dragged from when the mouse may be outside of that control. If you comment out the MyCanvas.Capture() and the Capture(Null) (which clears it) then you can no longer drop.

Related

Capturing the mouse pointer in a particular window in x11

I am able to obtain the list of all windows using _NET_CLIENT_LIST Atom property of x11. Using that, I choose a particular window of my interest, say the gedit window, and use XSetInputFocus and that will perfectly set the keyboard inputs and controls to the gedit window.
Now my question is, is there a similar function in X11 such that we can set the mouse focus to a particular window, such that any mouse clicks or selections will be confined to that particular window only.
I tried XGrabPointer, but with no success. It will simply freeze the mouse and no further mouse inputs will be displayed on screen (like mouse clicks; I can just see the mouse pointer, I can also move it, but it doesn't perform any click operations).
You should be able to poll for mouse events and, if the user tries to move out of the rectangle you should be able to reposition it. If you don't keep the pointer out of the other window(s), I don't think you can prevent mouse clicks from reaching them, but that may be possible.

previewmousewheel not getting raised when mouse is not on the control in wpf

I have a combobox control's previewmousewheel event been handled. When my mouse is on the control and i move the center wheel of my mouse then this event gets raised. But when my mouse is away from the control and i move the center wheel of my mouse then this event does not get raised.
Can anybody please explain me why is this happening?
If I want to raise an event when my mouse is away from the control then which event should I handle?
This is expected behaviour.
If the mouse cursor is not positioned over the control then no mouse events are routed through it. You wouldn't expect a mouse click event to be routed through it if the cursor was over a different control would you?
If you want this behaviour then I would suggest that you handle the mousewheel event in the page/view and route it from there, be cautious though as user expectation is for mouse and keyboard events to be handled by the in focus item.
In those cases that the user would expect the event to be forwarded to the control you could use Mouse.Capture(someControl) and Mouse.Capture(null) to stop the forwarding.
You should only use this when it makes sense. E.g. when dragging a scrollbar, when you started to drag on the thumb but are not required to stay on top of it as long as you keep the left mouse button down.
When using Mouse.Capture() make sure you always provide a way back from capturing.

monitor mousemove event in wpf

I'm trying to monitor the mouse movement over the application window
so that whenever the mouse moves its coordinates are reflected in two text conrols
Is it possible to do it in XAML only (without code)?
No, you have to write code. Getting mouse position is only doable by calling the Mouse.GetPosition method. This isn't something you can represent in XAML.

MouseCapture prevents all mouse based triggers from firing in WPF

I am using CaptureMouse() during a drag and drop operation to make sure I don't miss the MouseUp event, but this seems to prevent any mouse events reaching any other objects on my Canvas. This means that my IsMouseOver based triggers don't work, but I need them to indicate valid locations where the object can be dropped.
Am I doing this wrong, or is there a way of making sure everything on my Canvas still gets mouse events?
Are the elements part of the SubTree of your canvas? or outside of the canvas? If they are within then you could probably use the Capture method that takes a CaptureMode.
Mouse.Capture(elementToCapture, CaptureMode.SubTree);
Alternatively, you should look at the DragDrop class and consider using the Drop event instead?

WPF MouseMove Event Polling

I've created a WPF application where the title bar and chrome are turned off. I have a border around the entire app, with the idea that it would act like the chrome in some regards. The first thing I'm trying to do is have the mousemove event capture the movement of the mouse when the mouse is clicked, so that the window moves with the mouse. The problem is that if the mouse moves too quickly, it manages to leave the window and therefore the mousemove no longer fires. I've been able to do this with a normal WinForm with no problems regardless of the speed of the mouse. Is there any way to do this more efficiently, or perhaps tune the polling of the mousemove? Perhaps a different container other than border that would perform better?
Try Me.DragMove in the window's left click event handler. It much better than most custom solutions.
When the user clicks you should capture the mouse (see Mouse.Capture). That way, you'll get the mouse events regardless of whether the mouse cursor is over your element or not.

Resources