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