There is something about WPF mouse handling I obviously do not understand, so I’ll appreciate any help I can get. Sorry for making this lengthy – I’ve been told to provide enough context info so others can figure out what I am trying to accomplish.
I have a series of buttons that each contain the preview of an image. When zooming into a full image that I also display, I’d like to use the corresponding preview button as an indicator of which part of the full image I am actually zooming into. For that, I use an Adorner
that draws a simple rectangular box on top of the preview image, reflecting the zoomed area. Please see the screenshot for clarification – the button at the bottom left shows the zoomed area in an orange rectangle.
All of that works well already, and if I move the zoomed area around by clicking the full image and moving it, the orange box moves correspondingly as it should.
Now here’s my issue: I’d also like to be able to move the main zoom area around by putting the mouse down within the orange box on the preview button and then moving the box around. The way I am trying to implement this, I give the preview button event handlers for PreviewMouseDown
, PreviewMouseUp
and MouseMove
events like this:
Button prevBut = new Button();
prevBut.PreviewMouseDown += PrevBut_PreviewMouseDown;
prevBut.PreviewMouseUp += PrevBut_PreviewMouseUp;
prevBut.MouseMove += PrevBut_MouseMove;
PreviewMouseDown
checks whether the mouse position is actually within the orange box. If it is, it records the start position and captures the mouse for the button. PreviewMouseUp
releases the mouse capture again. MouseMove
should now get called and do some stuff to update the zoom depending on the mouse position respectively the change from the start position.
private void PrevBut_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
MouseStartPosRelativeToPreviewButton = e.GetPosition((Button)sender);
if ( [some calculation to verify that mouse position is within orange box] )
((Button)sender).CaptureMouse();
}
private void PrevBut_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
((Button)sender).ReleaseMouseCapture();
}
private void PrevBut_MouseMove(object sender, MouseEventArgs e)
{
if (((Button)sender).IsMouseCaptured)
{
Point PosRelativeToPreviewImage = e.MouseDevice.GetPosition((Button)sender);
.. [Do some calculations and update zoom plus the position of the orange box]
}
}
Problem is, PrevBut_MouseMove()
gets called regularly when the mouse is over the button (I verified that) but the calls STOP when a mouse button is pressed. In other words, if I log what happens, I see plenty of PrevBut_MouseMove()
calls when moving the mouse above the button, then when I click anywhere on the button, I get PrevBut_PreviewMouseDown()
, directly followed by PrevBut_PreviewMouseUp()
(once I released the mouse). Even if I keep the mouse button pressed for several seconds, not a single move gets recorded. Once I released the mouse button, there are plenty more PrevBut_MouseMove()
calls until the mouse leaves the button. As I said, I don’t understand this. Why would MouseMove
no longer fire when a mouse button is active?
The Adorner
(orange box) is set to IsHitTestVisible = false
, by the way, so as I understand it, it should not get in the way of mouse events. (Or could it?) I already spent many hours trying to find a workaround and could not make it work. Will appreciate any help you can give me. Thanks.