I implement a search for the characters entered from the database: when the user enters a letter, the words starting with the same letter are extracted from the database. The search works, the list of words appears, but the transfer of focus by pressing the down arrow from the input field to the selection options does not work. Illustration and sample code below.

work illustration

XAML

<StackPanel Margin="0,5,0,0"> <TextBox x:Name="textBoxSearch" KeyUp="textBoxSearch_KeyUp" Width="250" Height="23" /> <Border x:Name="borderHint" BorderThickness="1" BorderBrush="Black" Width="250" Height="95" Margin="0,2,0,0" Visibility="Collapsed" > <ScrollViewer VerticalScrollBarVisibility="Auto"> <StackPanel x:Name="stackHint"></StackPanel> </ScrollViewer> </Border> </StackPanel> 

The beginning of the method where I try to shift the focus

  /// <summary> /// Ввод текста в поле для поиска слова /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void textBoxSearch_KeyUp(object sender, KeyEventArgs e) { //если нажата стрелка вниз if (e.Key == Key.Down && borderHint.Visibility == Visibility.Visible) { //TODO: сделать перенос фокуса на первое слово в списке if (stackHint.Children.Count > 0) { scrollViewer.Focus(); //stackHint.Focus(); //stackHint.Children[0].Focus(); //var b = stackHint.Children[0].Focusable; } return; } //ссылка на вводимый текст string query = (sender as TextBox).Text; //очищаем бордер от предыдущих элементов this.stackHint.Children.Clear(); //управление видимостью бордера if (query.Length == 0) { //если ничего не введено, прячем бордер this.borderHint.Visibility = System.Windows.Visibility.Collapsed; return; } else { //если что-то введено, то показываем бордер this.borderHint.Visibility = System.Windows.Visibility.Visible; } //запрашиваем подходящие слова List<string> hints = await ((ListWordsViewModel)this.DataContext).GetHints(query); //показываем в зависимости от результата if (hints.Any()) { AddHints(hints); } else { this.stackHint.Children.Add(new TextBlock() { Text = "Ничего не найдено." }); } } private void AddHints(List<string> hints) { TextBlock block = null; foreach (var hint in hints) { //добавляем содержимое подсказки block = new TextBlock(); block.Text = hint; //стиль block.Cursor = Cursors.Hand; //События мыши block.MouseLeftButtonUp += (sender, e) => { //вводим выбранную подсказку this.textBoxSearch.Text = (sender as TextBlock).Text; //прячем остальные подсказки this.borderHint.Visibility = Visibility.Collapsed; //передаем нужный текст во ViewModel ((ListWordsViewModel)this.DataContext).SearchText = this.textBoxSearch.Text; }; block.MouseEnter += (sender, e) => { TextBlock b = sender as TextBlock; b.Background = Brushes.LightBlue; }; block.MouseLeave += (sender, e) => { TextBlock b = sender as TextBlock; b.Background = Brushes.Transparent; }; //отображение подсказки this.stackHint.Children.Add(block); } } 

Next in this method comes the extraction of the right words from the database and filling this.stackHint TextBlock with the right words. So I want to transfer the focus to the first TextBlock so that the arrow can be selected from the list. I went through the steps, the condition fulfills, but for some reason the focus in the interface does not change. What do you advise?

PS

  if (stackHint.Children.Count > 0) { scrollViewer.Focus(); var b = stackHint.Children[0].Focusable; } 

The focus on the scrollViewer shifting, but it’s still impossible to go further with the arrow. But b == false

  • But this is not it: ru.stackoverflow.com/a/576463/10105 ? - VladD
  • Well, if you have stackHint.Children[0].Focusable == false , then show how you add elements to stackHint . - VladD
  • @VladD on the link are played with ComboBox, I have everything differently - Bulson
  • @VladD added the full version of what. - Bulson
  • one
    StackPanel, which you use as a container, supports only the simplest layout of elements and hardly supports navigation. Try replacing it with a ListBox for example. - Anton Papin

2 answers 2

StackPanel , which you use as a container, supports only the simplest layout of elements and does not support navigation. Try replacing it with a more advanced container, for example ListBox .

  • one
    Thanks, with ListBox earned. - Bulson

I had quite a focus shifting in your code when I replaced

 block = new TextBlock(); 

on

 block = new TextBlock() { Focusable = true }; 

and also commented out

 scrollViewer.Focus(); 

and uncommented

 stackHint.Children[0].Focus(); 

Debugging UI with focus in step-by-step mode is not the best idea. The fact is that when switching to a debugger, the application loses focus, and accordingly behaves in a wrong way. Alas. It is necessary to use logging.

  • Thank you, I’ll check it now ... I’m following the advice of Anton Papin to stack glasspanel on a listbox and it all worked, I'll try to do an hour as you advise. - Bulson
  • @Bulson: Yeah, listbox also has ListBoxItem s with the attribute Focusable == true . - VladD
  • The focus appears, yes. But, after selecting and pressing Enter does not select the desired item. - Bulson
  • @Bulson: Well, yes, but why should he? Do you have the same panel from pressing Enter do not disappear by themselves? In Combobox it is written in its logic, and where are you? - VladD
  • Yes, I forgot to subscribe to a push event, yes. And with the ListBox, I liked the option that it immediately highlights the element with color in focus, and not as a panel just dotted. Thank you, I'll sort it out further ... - Bulson