在.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
停止工作! 为什么?!我无法理解鼠标处理程序如何链接到我的键盘快捷键!
答案 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