PreviewMouseLeftButtonDown и InputBindings

С помощью .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 которые регистрируются в статическом конструкторе. Например:

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

InputBinding зависит от PreviewMouseLeftButtonDown?!

Теперь, когда я установил e.Handled в true в моем PreviewMouseLeftButtonDown хендлер, мой InputBindingперестань работать! Зачем?! Я не могу понять, как обработчик мыши связан с моими сочетаниями клавиш!

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 нам просто пустая кнопка или любой элемент фокусировки, который вам нравится. Тогда это работает хорошо.

Итак, мой взгляд на проблему таков: причина не в событиях мыши, она в фокусе.

PreviewMouseLeftButtonDown срабатывает перед всеми другими перенаправленными событиями. Когда вы устанавливаете здесь значение e.Handled = true, вы фактически не допускаете срабатывания других событий. Это также учитывает другие перенаправленные события PreviewX, и цель состоит в том, чтобы остановить его. Вы можете добавить в код обработчики, которые будут получать эти события независимо от того, установлены они как обработанные или нет. Очень удобно для проверки бездействия и т. Д.

Как это:

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


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

Последний параметр заставит вас перехватить MouseUpEvents, даже если они обработаны.

Я не уверен, как вы можете сделать это со своими привязками из коробки, но это может быть возможно.

Надеюсь, это поможет как минимум.

ура

Stian

Другие вопросы по тегам