WPF和Windows 8中带有列表框的触摸/鼠标事件行为



当我试图在windows 8机器上处理列表框上的鼠标和触摸输入时,我得到了我认为意外的行为(因为这与在windows 7上运行相同的软件不同)。

这是我处理事件的功能/方法

Private Sub Drag_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Input.InputEventArgs) Handles lvItems.PreviewMouseDown, lvItems.PreviewTouchDown

当我让它同时处理鼠标和触摸输入时,(PreviewTouchDownPreviewMouseDown)它将接收两个事件(触摸事件和鼠标按钮事件),即使我在TouchEventArgs上为首先引发的事件设置了event.Handled = True

若我从事件处理程序中删除了对PreviewTouchDown事件的处理,那个么我就不会接收到PreviewMouseDown事件。

我需要的是每次触摸/点击只能调用一次该方法。我无法删除PreviewMouseDown,因为它不仅用于触摸屏。一次触摸同时通过触摸事件和鼠标事件会破坏我们的功能。

在windows 7上,我只接收触摸事件,因为我设置handled=true,所以鼠标事件被取消。

在windows 8上,触摸事件可以升级为鼠标事件。这有时很方便,因为它允许我使用触摸在Win8(而不是在Win7下)中打开组合框,有时这是不需要的,正如你所发现的。另请参阅JoshB的文章以获得更准确的解释。

在我的例子中,我在鼠标事件处理程序中检查e.StylusDevice是否为null(当处理鼠标时,它为null,而当处理触摸事件时则不是)。也许这对你也有帮助?

例如,我制作了一个ZoomGrid,它可以监听鼠标和触摸。在Windows 7下没有问题,但在Windows 8下,触摸移动后也会触发平移行为。正在检查e.StylusDevice!=null修复了它。

    private void MainGridMouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton != MouseButtonState.Pressed) return;
        if (!isDraggingBackground || e.StylusDevice != null) return;
        var curPosition = e.GetPosition(sender as UIElement);
        var delta = curPosition - startPosition;
        var rectsMatrix = ((MatrixTransform)RenderTransform).Matrix;
        rectsMatrix.Translate(delta.X, delta.Y);
        Offset = new Point(rectsMatrix.OffsetX, rectsMatrix.OffsetY);
        RenderTransform = new MatrixTransform(rectsMatrix);
        e.Handled = true;
    }

我解决这个问题的方法是检测计算机是否运行Windows 8,如果是,则不设置Handled,这样就不会发生与鼠标相关的事件。

If Not My.Computer.Info.OSFullVersion.Contains("Windows 8") Then
    e.Handled = True
End If

最新更新