WPF应用程序中的虚假和丢失鼠标事件

时间:2015-12-31 16:00:19

标签: wpf events

我有一个WPF应用程序,有两个相互重叠的画布。 。 。

<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"/>

我在第一个画布上绘制了一些几何体,并在第二个画布上绘制了一个矩形来表示感兴趣的区域(ROI),使用鼠标按下事件开始绘图,绘图时鼠标移动事件(调整大小或定位)矩形和用于结束绘图的Mouse-up事件。

除非它没有可靠地处理事件。它获得了初始的Mouse-down事件来启动它。它会连续获得鼠标移动事件 - 无论鼠标是否正在移动 - 它根本不会获得Mouse-up事件,也不会获得任何后续的鼠标按下事件,比如说我加倍 - 点击鼠标     事件处理程序代码如下所示。 。 。

        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);
            }
        }

...我尝试将鼠标暂停在半空中并将其放在毛巾上以消除任何可能导致虚假移动事件而无任何益处的振动,无论如何不会导致后续上下不动事件

注意:我在另一台计算机上尝试了这个,结果完全相同。

1 个答案:

答案 0 :(得分:1)

如果您提供问题的最小化工作示例(特别是您的ROIcnvMouseDown和ROIcnvMouseUp方法都缺失,那么您的所有属性声明都会得到更好的响应)。问题可能是由于您新创建的Path对象干扰了鼠标消息,如果是这样,那么可以通过将其IsHitTestVisible属性设置为false来修复它。需要一个最小的例子来确定这一点。

更新:对不起,我的不好,我一定把剪切贴在我的测试应用中。尝试捕获鼠标以响应鼠标按下事件:

private void ROIcnvMouseDown(object sender, MouseButtonEventArgs e)
{
    MouseLineBegin = Mouse.GetPosition(ROIcnv);
    bMouseDown = true;
    Mouse.Capture(sender as IInputElement);
}

当然,你需要释放它以响应MouseUp:

private void ROIcnvMouseUp(object sender, MouseButtonEventArgs e)
{
    MouseLineEnd = Mouse.GetPosition(ROIcnv);
    bMouseDown = false;
    Mouse.Capture(sender as IInputElement, CaptureMode.None);
    ROIcnv.Children.Clear();
}

我做的另一件事是调用ROIcnv.Children.Clear();以响应MouseUp,因为我假设您不再希望选择矩形可见。在我的机器上,这不会导致任何虚假的鼠标移动事件。

这会回答这个问题吗?