KeyBinding в UserControl не работает, когда TextBox имеет фокус

Следующая ситуация. У меня есть UserControl с пятью ключами. Когда TextBox имеет фокус, привязки клавиш для остановки запуска UserControl.

Есть ли способ исправить эту «проблему»?

            

Кажется, что функциональные клавиши ( F1 и т. Д.) И ALT + [ключ] работают. Я предполагаю, что модификаторы CTRL и SHIFT каким-то образом «блокируют» событие от барботажа до UserControl.

Причина в том, что некоторые привязки ввода работают, а некоторые нет, что элемент управления TextBox ловит и обрабатывает некоторые привязки клавиш. Например, он обрабатывает CTRL + V для вставки, CTRL + Home для перехода к началу текста и т. Д. Другие комбинации клавиш, такие как CTRL + F3, с другой стороны, не обрабатываются TextBox, и поэтому они будут пузыряться вверх.

Если бы вы просто хотели отключить привязку ввода TextBox, это было бы просто – вы могли бы использовать команду ApplicationCommands.NotACommand , которая отключила бы поведение по умолчанию. Например, в следующем случае вставка с CTRL + V будет отключена:

      

Тем не менее, сделать его пузырь до пользовательского контроля немного сложнее. Мое предложение состоит в том, чтобы создать прикрепленное поведение, которое будет применяться к UserControl, зарегистрировать его событие PreviewKeyDown и выполнить необходимые привязки для ввода до того, как они достигнут TextBox. Это будет иметь приоритет для UserControl, когда выполняются входные привязки.

Я написал базовое поведение, которое обеспечивает эту функциональность, чтобы вы начали:

 public class InputBindingsBehavior { public static readonly DependencyProperty TakesInputBindingPrecedenceProperty = DependencyProperty.RegisterAttached("TakesInputBindingPrecedence", typeof(bool), typeof(InputBindingsBehavior), new UIPropertyMetadata(false, OnTakesInputBindingPrecedenceChanged)); public static bool GetTakesInputBindingPrecedence(UIElement obj) { return (bool)obj.GetValue(TakesInputBindingPrecedenceProperty); } public static void SetTakesInputBindingPrecedence(UIElement obj, bool value) { obj.SetValue(TakesInputBindingPrecedenceProperty, value); } private static void OnTakesInputBindingPrecedenceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((UIElement)d).PreviewKeyDown += new KeyEventHandler(InputBindingsBehavior_PreviewKeyDown); } private static void InputBindingsBehavior_PreviewKeyDown(object sender, KeyEventArgs e) { var uielement = (UIElement)sender; var foundBinding = uielement.InputBindings .OfType() .FirstOrDefault(kb => kb.Key == e.Key && kb.Modifiers == e.KeyboardDevice.Modifiers); if (foundBinding != null) { e.Handled = true; if (foundBinding.Command.CanExecute(foundBinding.CommandParameter)) { foundBinding.Command.Execute(foundBinding.CommandParameter); } } } } 

Применение:

       

Надеюсь это поможет.

Решение Ади Лестера хорошо работает. Вот аналогичное решение, использующее Behavior. Код C #:

 public class AcceptKeyBinding : Behavior { private TextBox _textBox; ///  /// Subscribes to the PreviewKeyDown event of the . ///  protected override void OnAttached() { base.OnAttached(); _textBox = AssociatedObject as TextBox; if (_textBox == null) { return; } _textBox.PreviewKeyDown += TextBoxOnPreviewKeyDown; } private void TextBoxOnPreviewKeyDown(object sender, KeyEventArgs keyEventArgs) { var uielement = (UIElement)sender; var foundBinding = uielement.InputBindings .OfType() .FirstOrDefault(kb => kb.Key == keyEventArgs.Key && kb.Modifiers == keyEventArgs.KeyboardDevice.Modifiers); if (foundBinding != null) { keyEventArgs.Handled = true; if (foundBinding.Command.CanExecute(foundBinding.CommandParameter)) { foundBinding.Command.Execute(foundBinding.CommandParameter); } } } ///  /// Unsubscribes to the PreviewKeyDown event of the . ///  protected override void OnDetaching() { if (_textBox == null) { return; } _textBox.PreviewKeyDown -= TextBoxOnPreviewKeyDown; base.OnDetaching(); } } 

И XAML:

         

В дополнение к Adi Lester его (очень полезный) ответ я хотел бы предложить некоторые улучшения / расширения, которые помогли мне с моей реализацией.

Gesture.Matches

Обнаруженный поиск также можно выполнить, вызвав Gesture.Matches. Измените запрос foundBinding Linq на следующее:

 KeyBinding foundBinding = ((UIElement)this).InputBindings .OfType() .FirstOrDefault(inputBinding => inputBinding.Gesture.Matches(sender, eventArgs)); 

MouseBinding

Кроме того, вы также можете определить MouseBindings.

  

Затем вам также необходимо подписаться на PreviewMouseEvents, например PreviewMouseUp и PreviewMouseDoubleClick. Реализация тогда почти такая же, как для KeyBindings.

 private void OnTextBoxPreviewMouseUp(object sender, MouseButtonEventArgs eventArgs) { MouseBinding foundBinding = ((UIElement)this).InputBindings .OfType() .FirstOrDefault(inputBinding => inputBinding.Gesture.Matches(sender, eventArgs)); if (foundBinding != null) { eventArgs.Handled = true; if (foundBinding.Command.CanExecute(foundBinding.CommandParameter)) { foundBinding.Command.Execute(foundBinding.CommandParameter); } } } 
    

keyPressPlaceHoler – это имя контейнера вашего целевого uielement

не забудьте установить Focusable="True" в usercontrol

  • Разница между TargetType = "controlType" и TargetType = "{x: Тип controlType}"
  • Переключение UWP в Style Setter не работает
  • Доступ к переменной codebehind в XAML
  • Как получить доступ к элементу управления внутри шаблона данных в пользовательском интерфейсе C # Metro в коде
  • Как получить размер текущего экрана в WPF?
  • Как создать вкладки трапеции в элементе управления вкладками WPF
  • WPF: слайдер с событием, которое запускается после того, как пользователь перетаскивает
  • Лучший способ использовать векторное изображение в WPF?
  • Можете ли вы определить несколько TargetTypes для одного стиля XAML?
  • наследовать стиль от стиля по умолчанию
  • Ошибка привязки элемента ElementName
  • Interesting Posts

    Используйте USB-цифровую клавиатуру с телефонным набором текста?

    Как преобразовать данные, полученные через Meteor.publish?

    Можно ли использовать 2 Mac mini для создания распределенной вычислительной системы

    Глобальный Ключ для клавиатуры от службы Windows

    При использовании SASS, как я могу импортировать файл из другого каталога?

    Сжигает ли DVD / CD медленнее, чтобы гарантировать, что у него не будет ошибок?

    Как CountDownLatch используется в многопоточности Java?

    Android Studio – Как увеличить размер выделенной кучи

    Как получить цветовые вариации

    Как заставить хром перестать запрашивать меня при загрузке PDF-файлов?

    C #, чтобы проверить, является ли строка целым числом?

    Как использовать интернет-соединение? (Одноранговая сеть)

    Создание имени переменной с использованием значения String

    Ядро Java swingWorker работает, но не получено или передано сообщение

    Как отключить или переназначить ключ «Windows»?

    Давайте будем гением компьютера.