Keyboard.Focus не работает в текстовом поле в WPF

Я ударяю головой о том, что выглядит такой простой проблемой для исправления в wpf, но мне еще предстоит выяснить, почему я не могу заставить приложение вести себя в соответствии с моим планом.

У меня есть небольшое окно поиска, которое появляется в моем приложении wpf, когда пользователь нажимает ctrl + f. Все, что я хочу, это то, что каретка будет мигать внутри текстового поля окна поиска, готового принять любой пользовательский ввод, не нажимая на него пользователя. Вот код xaml для текстового поля, которое видимо, включено, доступно для проверки, tabstopable и focusable.

   <TextBox x:Name="SearchCriteriaTextBox" Text="{Binding SearchCriteria}" Focusable="True" IsEnabled="True" IsTabStop="True" IsHitTestVisible="True" Style="{DynamicResource SearchTextBoxStyle}" Grid.Column="1" Margin="5,10,0,5" />

В коде позади я вызываю этот метод, когда влияет видимость окна поиска. окно поиска загружается в начале приложения.

    /// <summary>
    /// Handles events triggered from focusing on this view.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="dependencyPropertyChangedEventArgs">The key event args.</param>
    private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        if (!((bool) dependencyPropertyChangedEventArgs.NewValue))
        {
            return;
        }

        SearchCriteriaTextBox.Focus();
        Keyboard.Focus(SearchCriteriaTextBox);
        SearchCriteriaTextBox.Select(0, 0);

        if (SearchCriteriaTextBox.Text.Length > 0)
        {
            SearchCriteriaTextBox.SelectAll();
        }
    }

Проблема в том, что код вызывается, компонент становится IsFocused = true, но не получает фокус клавиатуры. Я что-то упускаю? Если другой контроль не держит дерзко в фокусе клавиатуры, который, я уверен, я не кодировал, почему этот кусок довольно простого кода не будет работать должным образом.

Ответы

Ответ 1

В качестве обходного пути вы можете попробовать использовать Dispatcher, чтобы установить фокус на более поздний DispatcherPriority, например Input

Dispatcher.BeginInvoke(DispatcherPriority.Input,
    new Action(delegate() { 
        SearchCriteriaTextBox.Focus();         // Set Logical Focus
        Keyboard.Focus(SearchCriteriaTextBox); // Set Keyboard Focus
     }));

Из описания вашей проблемы звучит так, будто у вас нет набора фокусов клавиатуры. WPF может иметь несколько областей фокусировки, поэтому несколько элементов могут иметь логическую фокусировку (IsFocused = true), однако только один элемент может иметь клавиатурный фокус и получать ввод с клавиатуры.

Код, который вы отправили, должен правильно настроить фокус, поэтому после этого нужно будет что-то предпринять, чтобы перенести Focus Keyboard из вашего TextBox. Установив фокус на более поздний приоритет диспетчера, вы убедитесь, что настройка фокуса клавиатуры на ваш SearchCriteriaTextBox выполняется последним.

Ответ 2

Если это помогает кому-либо, у меня возникла эта проблема, и у моего приложения было главное окно с несколькими пользовательскими элементами управления, размещенными в отдельных сетках с привязкой данных видимости. Поскольку сетки были там, когда приложение было построено,.Focus(), вызываемый Loaded или Constructor, будет вызываться во время сборки, а не во время видимости.

В любом случае я исправил его, вызвав .Focus() в событии MouseEnter сетки. Прекрасно работает для меня.

Ответ 3

Основываясь на решении Рэйчел, есть более простой способ.

в XAML добавить в TextBox Загруженный =

"Got_Loaded"и в коде позади

    private void Got_Loaded(object sender, RoutedEventArgs e)
    {
        Keyboard.Focus(((TextBox)sender));
    }