Reputation: 8271
I have a WPF app with two canvases which overlay each other . . .
<Canvas Name="GeometryCnv" Canvas.Top="0" Canvas.Left="0" Margin="10,21,315,251" />
<Canvas Name="ROIcnv" Background ="Transparent" Canvas.Top="0" Canvas.Left="0" Margin="10,21,315,251" MouseDown="ROIcnvMouseDown" MouseUp="ROIcnvMouseUp" MouseMove="ROIcnvMouseMove"/>
I draw some geometry on the first canvas and I draw a rectangle to denote a Region on Interest (ROI) on the second one, using the Mouse-down event to start the drawing, Mouse-move events while drawing (resizing or positioning) the rectangle, and the Mouse-up event to end the drawing.
Except that it's not handling the events reliably. It gets the initial Mouse-down event to start it. It gets Mouse-move events continuously - regardless of whether the mouse is moving - and it does not get the Mouse-up event at all, nor does it get any subsequent mouse down events, say if I double-click the mouse.
The event-handler code looks like this . . .
private void ROIcnvMouseDown(object sender, MouseButtonEventArgs e)
{
MouseLineBegin = Mouse.GetPosition(ROIcnv);
bMouseDown = true;
}
private void ROIcnvMouseUp(object sender, MouseButtonEventArgs e)
{
MouseLineEnd = Mouse.GetPosition(ROIcnv);
bMouseDown = false;
}
private void ROIcnvMouseMove(object sender, MouseEventArgs e)
{
iMM++; // counting mouse move events
ROIcnv.Children.Clear(); // clear the ROI canvas
if (bMouseDown) // if we're drawing now
{
MouseLineEnd = Mouse.GetPosition(ROIcnv);
// get the upper left and lower right = coords from the beginning and end points . . .
int ulx = 0;
int uly = 0;
int lrx = 0;
int lry = 0;
if (MouseLineEnd.X >= MouseLineBegin.X)
{
ulx = (int) MouseLineBegin.X;
lrx = (int) MouseLineEnd.X;
}
else
{
lrx = (int)MouseLineBegin.X;
ulx = (int)MouseLineEnd.X;
}
if (MouseLineEnd.Y >= MouseLineBegin.Y)
{
uly = (int)MouseLineBegin.Y;
lry = (int)MouseLineEnd.Y;
}
else
{
lry = (int)MouseLineBegin.Y;
uly = (int)MouseLineEnd.Y;
}
int h = Math.Abs(lry-uly);
int w = Math.Abs(lrx-ulx);
var rect = new Path
{
Data = new RectangleGeometry(new Rect(ulx, uly, w, h)),
Stroke = Brushes.Black,
StrokeThickness = 2
};
ROIcnv.Children.Add(rect);
}
}
... I've tried suspending the mouse in mid-air and resting it on towels to eliminate any vibrations that might cause spurious move events with no benefit, any anyway that wouldn't account for not getting subsequent up and down events.
Note: I tried this on another computer with exactly the same results.
Upvotes: 0
Views: 345
Reputation: 16119
You'll have much better responses if you provide a minimal, working example of your problem (specifically both your ROIcnvMouseDown and ROIcnvMouseUp methods are missing as are all of your property declarations). The problem is possibly due to your newly-created Path object interfering with the mouse messages, if so then it can be fixed by setting it's IsHitTestVisible
property to false
. Need a minimal example to determine this for sure though.
UPDATE: Sorry, my bad, I must have stuffed up the cut-n-paste into my test app. Try capturing the mouse in response to the mouse down event:
private void ROIcnvMouseDown(object sender, MouseButtonEventArgs e)
{
MouseLineBegin = Mouse.GetPosition(ROIcnv);
bMouseDown = true;
Mouse.Capture(sender as IInputElement);
}
And of course you need to release it in response to MouseUp:
private void ROIcnvMouseUp(object sender, MouseButtonEventArgs e)
{
MouseLineEnd = Mouse.GetPosition(ROIcnv);
bMouseDown = false;
Mouse.Capture(sender as IInputElement, CaptureMode.None);
ROIcnv.Children.Clear();
}
The other thing I've done is call ROIcnv.Children.Clear();
in response to MouseUp as I assume you no longer want the selection rectangle to be visible. On my machine this doesn't result in any spurious mouse move events.
Does that answer the question?
Upvotes: 1