Переход к следующему элементу управления нажатием клавиши Enter в WPF

Я хочу перейти к следующему элементу управления, когда я нажимаю клавишу Enter, а не клавишу Tab в приложении WPF MVVM. Как я могу это достичь?

Ответ Jay хорош, если вы хотите, чтобы он работал только для нескольких текстовых полей, но если вы хотите, чтобы все ваше приложение работало таким образом, я определенно одобряю ответ makwana.a. Вот моя модификация ответа makwana.a, который я использую в C #. Я также включил поддержку перехода на следующий элемент управления через enter, если активным элементом управления является флажок.

Также обратите внимание, что вместо использования свойства tag для обозначения того, следует ли перемещать фокус, я использую свойство AcceptsReturn текстового поля, поскольку оно по умолчанию имеет значение false, и вы установите его только в текстовые поля, которые вы хотите для использования в качестве многострочного, т. е. не должен фокусироваться на Enter Key.

Объявите эти обработчики событий в OnStartup void App.xaml

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.KeyDownEvent, new KeyEventHandler(TextBox_KeyDown)); EventManager.RegisterClassHandler(typeof(CheckBox), CheckBox.KeyDownEvent, new KeyEventHandler(CheckBox_KeyDown)); 

Вот остальные методы, необходимые для широкого применения приложения.

  void TextBox_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter & (sender as TextBox).AcceptsReturn == false) MoveToNextUIElement(e); } void CheckBox_KeyDown(object sender, KeyEventArgs e) { MoveToNextUIElement(e); //Sucessfully moved on and marked key as handled. //Toggle check box since the key was handled and //the checkbox will never receive it. if (e.Handled == true) { CheckBox cb = (CheckBox)sender; cb.IsChecked = !cb.IsChecked; } } void MoveToNextUIElement(KeyEventArgs e) { // Creating a FocusNavigationDirection object and setting it to a // local field that contains the direction selected. FocusNavigationDirection focusDirection = FocusNavigationDirection.Next; // MoveFocus takes a TraveralReqest as its argument. TraversalRequest request = new TraversalRequest(focusDirection); // Gets the element with keyboard focus. UIElement elementWithFocus = Keyboard.FocusedElement as UIElement; // Change keyboard focus. if (elementWithFocus != null) { if (elementWithFocus.MoveFocus(request)) e.Handled = true; } } 

редактировать

Я обновил код, чтобы отметить нажатие клавиши, как было обработано, если движение было успешным, а также переключить флажок, так как ключ был обработан и больше не будет доступен.

Ниже приведено свойство, которое я использовал для этого.

Во-первых, использование примера:

  

(UI – псевдоним пространства имен, где я определил следующее.)

Прилагаемое свойство:

 public static class FocusAdvancement { public static bool GetAdvancesByEnterKey(DependencyObject obj) { return (bool)obj.GetValue(AdvancesByEnterKeyProperty); } public static void SetAdvancesByEnterKey(DependencyObject obj, bool value) { obj.SetValue(AdvancesByEnterKeyProperty, value); } public static readonly DependencyProperty AdvancesByEnterKeyProperty = DependencyProperty.RegisterAttached("AdvancesByEnterKey", typeof(bool), typeof(FocusAdvancement), new UIPropertyMetadata(OnAdvancesByEnterKeyPropertyChanged)); static void OnAdvancesByEnterKeyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var element = d as UIElement; if(element == null) return; if ((bool)e.NewValue) element.KeyDown += Keydown; else element.KeyDown -= Keydown; } static void Keydown(object sender, KeyEventArgs e) { if(!e.Key.Equals(Key.Enter)) return; var element = sender as UIElement; if(element != null) element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); } } 

Вы также сказали «вместо вкладки», поэтому мне интересно, хотите ли вы отключить возможность использовать вкладку обычным способом. Я бы посоветовал это, так как это обычная, хорошо известная парадигма, но если это так, вы можете добавить обработчик PreviewKeyDown в прикрепленное свойство, проверить ключ табуляции и установить Handled = true для аргументов события ,

Пример решения: использование PreviewKeyDown в панели стека. Предварительный просмотр … является пузырем, поэтому событие можно обрабатывать на более высоком уровне. Возможно, вам придется обращаться с этим по-разному для разных типов элементов, например, кнопка, кажется, должна содержать ключ ввода и не изменять фокус на клавише ввода.

Вот xaml:

   Hello   World   test   

И вот код позади:

 private void StackPanel_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { TextBox s = e.Source as TextBox; if (s != null) { s.MoveFocus(new TraversalRequest( FocusNavigationDirection.Next)); } e.Handled = true; } } 

Это только песочница для доказательства концепции.

Счастливое кодирование …

Напишите этот код в событии onstartup файла вашего приложения

 EventManager.RegisterClassHandler(GetType(TextBox), TextBox.KeyDownEvent, New RoutedEventHandler(AddressOf TextBox_KeyDown)) 

затем определите TextBox_KeyDown sub как

  Private Sub TextBox_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Input.KeyEventArgs) If e.Key = Key.Enter And TryCast(sender, TextBox).Tag <> "1" Then ' Creating a FocusNavigationDirection object and setting it to a ' local field that contains the direction selected. Dim focusDirection As FocusNavigationDirection = FocusNavigationDirection.Next ' MoveFocus takes a TraveralReqest as its argument. Dim request As New TraversalRequest(focusDirection) ' Gets the element with keyboard focus. Dim elementWithFocus As UIElement = TryCast(Keyboard.FocusedElement, UIElement) ' Change keyboard focus. If elementWithFocus IsNot Nothing Then elementWithFocus.MoveFocus(request) End If End If End Sub 

Я использовал свойство «tag» текстового поля для перехода к фокусу перемещения. т.е. если некоторое время вы не хотите переходить к следующему элементу управления при нажатии клавиши ввода (в случае многострочного текстового поля, где требуется ввести новую строку). Просто установите свойство тега на 1.

Надеемся на эту помощь: используйте AttachedProperty http://madprops.org/blog/enter-to-tab-as-an-attached-property/

 public class EnterKeyTraversal { public static bool GetIsEnabled(DependencyObject obj) { return (bool)obj.GetValue(IsEnabledProperty); } public static void SetIsEnabled(DependencyObject obj, bool value) { obj.SetValue(IsEnabledProperty, value); } static void ue_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { var ue = e.OriginalSource as FrameworkElement; if (e.Key == Key.Enter) { e.Handled = true; ue.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); } } private static void ue_Unloaded(object sender, RoutedEventArgs e) { var ue = sender as FrameworkElement; if (ue == null) return; ue.Unloaded -= ue_Unloaded; ue.PreviewKeyDown -= ue_PreviewKeyDown; } public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(EnterKeyTraversal), new UIPropertyMetadata(false, IsEnabledChanged)); static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ue = d as FrameworkElement; if (ue == null) return; if ((bool)e.NewValue) { ue.Unloaded += ue_Unloaded; ue.PreviewKeyDown += ue_PreviewKeyDown; } else { ue.PreviewKeyDown -= ue_PreviewKeyDown; } } } 

  

Сначала произошло добавление триггера к каждому элементу, который будет вызываться при PreviewKeyDown . Также добавьте свойство Dependency и свяжите FrameworkElement которым вы не сможете сосредоточиться. Внутри триггера установите параметр Focus to binded element.

Использование кода:

Я придумал код ниже. Обратите внимание, что он не устанавливает e.Handled. Кроме того, MoveFocus_Next не возвращает, было ли фокус перемещения успешным, но если аргумент не равен нулю. Вы можете добавлять или удалять типы элементов управления для обработки по мере необходимости. Код был написан для MainWindow приложения, но также обрабатывает другие windows. Вы также можете адаптировать код для вызова из события App_Startup.

 using System.Windows; using System.Windows.Controls; using System.Windows.Input; public partial class MainWindow : Window { private bool MoveFocus_Next(UIElement uiElement) { if (uiElement != null) { uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); return true; } return false; } public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { EventManager.RegisterClassHandler(typeof(Window), Window.PreviewKeyUpEvent, new KeyEventHandler(Window_PreviewKeyUp)); } private void Window_PreviewKeyUp(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { IInputElement inputElement = Keyboard.FocusedElement; if (inputElement != null) { System.Windows.Controls.Primitives.TextBoxBase textBoxBase = inputElement as System.Windows.Controls.Primitives.TextBoxBase; if (textBoxBase != null) { if (!textBoxBase.AcceptsReturn) MoveFocus_Next(textBoxBase); return; } if ( MoveFocus_Next(inputElement as ComboBox) || MoveFocus_Next(inputElement as Button) || MoveFocus_Next(inputElement as DatePicker) || MoveFocus_Next(inputElement as CheckBox) || MoveFocus_Next(inputElement as DataGrid) || MoveFocus_Next(inputElement as TabItem) || MoveFocus_Next(inputElement as RadioButton) || MoveFocus_Next(inputElement as ListBox) || MoveFocus_Next(inputElement as ListView) || MoveFocus_Next(inputElement as PasswordBox) || MoveFocus_Next(inputElement as Window) || MoveFocus_Next(inputElement as Page) || MoveFocus_Next(inputElement as Frame) ) return; } } } } 
  • Убедитесь, что OnPropertyChanged () вызывается в streamе пользовательского интерфейса в приложении MVVM WPF
  • Как точно встраиваемые свойства работают в WPF?
  • Связывающие свойства в коде
  • Как я могу преобразовать 'System.Windows.Input.Key' в 'System.Windows.Forms.Keys'?
  • Зачем использовать MVVM?
  • Как установить стиль WPF Window Style в app.xaml?
  • WPF: привязать DataGrid к списку
  • Таймер WPF Как таймер C #
  • WPF привязка данных к интерфейсу, а не к фактическому объекту - возможность литья?
  • Есть ли эквивалент MessageBox в WPF?
  • Загрузите BitmapImage WPF из System.Drawing.Bitmap
  • Interesting Posts

    генерировать последовательность внутри группы в R

    Можете ли вы совместно использовать принтер LAN из домашней группы Windows 7 в домен Windows Vista?

    Драйвер дисплея перестает работать и был восстановлен.

    Как перечислить все объекты AWS S3 в ведре с помощью Java

    LINQ: передача lambda-выражения в качестве параметра для выполнения и возврата методом

    Как работает оператор побитового дополнения (~ тильда)?

    Как восстановить поврежденные файлы, найденные sfc / scannow? «Windows Resource Protection обнаружила поврежденные файлы, но не смогла исправить некоторые из них».

    Языковые настройки Windows 8 не меняют язык во всем мире

    FileSystemWatcher для просмотра пути UNC

    Почему я не могу активировать профиль Maven2 из другого профиля?

    Переименование файлов в пакетном файле

    Значение сообщений хореографа в Logcat

    Как использовать инструменты: overrideLibrary в файле build.gradle?

    Как получить ширину и высоту многомерного массива?

    Прочитайте несколько файлов CSV в отдельных кадрах данных

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