【问题标题】:PreviewMouseLeftButtonDown and InputBindings relationshipPreviewMouseLeftButtonDown 和 InputBindings 的关系
【发布时间】:2014-08-28 11:25:59
【问题描述】:

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

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

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

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

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

InputBinding 依赖于 PreviewMouseLeftButtonDown?!

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

【问题讨论】:

    标签: wpf inputbinding


    【解决方案1】:

    我现在能想到的唯一原因是:您将输入绑定注册到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 我们只是一些空按钮或任何您喜欢的可聚焦元素。然后就可以了。

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

    【讨论】:

    • 虽然我(还)无法在我的项目中使用它,但这种解释似乎是合理的。确实,我的UserControl 没有焦点。
    • @l33t,我能够重现您的问题并使用提到的代码修复它,但您的代码确实可能更复杂。检查CommandManager code 也指向主要的罪魁祸首(例如OnCanExecute 处理程序)。但总而言之,这更像是一种猜测,所以我希望你能尽快找到解决问题的确切方法!
    【解决方案2】:

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

    像这样:

    AddHandler(MouseUpEvent, new MouseButtonEventHandler(YourHandler), true);
    
    
    private void YourHandler(object sender, MouseButtonEventArgs e)
    {
        // Do your magic here!
    }
    

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

    我不确定如何使用开箱即用的绑定来执行此操作,但它可能是可能的。

    希望它至少能有所帮助。

    干杯

    斯蒂安

    【讨论】:

    • 谢谢!但是为什么 PreviewMouseLeftButtonDown 事件会影响键盘事件呢?
    • @l33t 哦!我在那里读了你的帖子有点快。嗯……嗯,这确实很奇怪……你能发布更多你的代码吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    相关资源
    最近更新 更多