PreviewMouseLeftButtonDown和InputBindings关系

时间:2014-08-28 11:25:59

标签: wpf inputbinding

.NET 4.5.1上使用Windows 8.1 Pro。在我的UserControl我有网格。我需要在此网格中预览和处理鼠标事件。所以我覆盖了PreviewMouseLeftButtonDown事件:

    myGrid.PreviewMouseLeftButtonDown +=
        new MouseButtonEventHandler(myGrid_PreviewLeftButtonDown);
}

private void myGrid_PreviewLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // ...
    e.Handled = true; // <-- IMPORTANT!
}

我的UserControl也有一些InputBindings正在静态构造函数中注册。 E.g:

CommandManager.RegisterClassInputBinding(typeof(MyUserControl),
    new KeyBinding(MyCommands.SelectAll, new KeyGesture(Key.A, ModifierKeys.Control)));

InputBinding依赖于PreviewMouseLeftButtonDown?!

现在,当我在e.Handled处理程序中将true设置为PreviewMouseLeftButtonDown时,InputBinding停止工作! 为什么?!我无法理解鼠标处理程序如何链接到我的键盘快捷键!

2 个答案:

答案 0 :(得分:2)

我现在可以提出的唯一原因如下:您将输入绑定注册到MyUserControl,因此要激活此UserControl必须具有焦点。当您在网格级别处理鼠标事件时,您不允许此输入转到UserControl。所以,没有输入 - 没有焦点,没有焦点 - 没有命令激活。

假设我们稍微更改了代码:

private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
    FocusManager.SetFocusedElement(this, myUC);
}

myUC是我们的UserControl。但是UserControl不可调焦,所以我们将在其中添加一点焦点转移:

protected override void OnGotFocus(RoutedEventArgs e)
{
    btn.Focus();
    base.OnGotFocus(e);
}

btn我们只是一些空的Button或你喜欢的任何可聚焦元素。然后就可以了。

所以,我对这个问题的看法是:原因不在鼠标事件中,而是在焦点

答案 1 :(得分:1)

在所有其他路由事件之前触发PreviewMouseLeftButtonDown。当你在这里设置e.Handled = true时,你有效地阻止其他事件被触发。这也解释了其他PreviewX路由事件,目的是阻止它。您可以在代码中添加处理程序,无论是否将其设置为已处理,都将获得这些事件。非活动检查非常方便等。

像这样:

AddHandler(MouseUpEvent, new MouseButtonEventHandler(YourHandler), true);


private void YourHandler(object sender, MouseButtonEventArgs e)
{
    // Do your magic here!
}

最后一个参数会导致您捕获MouseUpEvents,即使它们已被处理。

我不确定如何使用开箱即用的绑定来完成此操作,但这可能是可能的。

希望它至少可以帮助你。

干杯

了Stian