Я пытаюсь воспроизвести функцию автозаполнения, которую вы найдете на главной странице Google. Таким образом, когда вы начинаете вводить текст в текстовое поле, вы получаете раскрывающийся список предложений, и с помощью клавиши со стрелкой вверх или вниз вы можете циклически перемещаться по этому списку. Я в значительной степени там с этой функциональностью. Код, который я перечислил ниже, демонстрирует проблему.
Когда вы начинаете печатать в первый раз и отображается список предложений, нажатие клавиши со стрелкой вверх, когда текстовое поле все еще находится в фокусе, должно привести к тому, что последний элемент в списке предложений будет сфокусирован и выбран.
В моем примере ниже выбран предпоследний элемент, и я не могу понять, почему. Я жестко закодировал предложения в моем примере, поэтому нет необходимости печатать. Простое нажатие клавиши со стрелкой вверх должно продемонстрировать проблему.
<Window x:Class="MyTestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525"
Loaded="Window_Loaded">
<StackPanel>
<TextBox x:Name="nameTextBox"
Text="hello world!"
PreviewKeyDown="nameTextBox_PreviewKeyDown" />
<ListBox x:Name="suggestionListBox"
DisplayMemberPath="Name"
SelectionChanged="suggestionListBox_SelectionChanged"
PreviewKeyDown="suggestionListBox_PreviewKeyDown" />
<Label x:Name="output" />
</StackPanel>
</Window>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace MyTestApplication
{
public partial class MainWindow : Window
{
private const int NOT_SELECTED = -1;
public MainWindow()
{
InitializeComponent();
suggestionListBox.ItemsSource = new[]
{
new { Name = "aaaaaa"},
new { Name = "bbbbbbbb"},
new { Name = "cccc"},
new { Name = "ddddd"},
new { Name = "eeeeee"},
new { Name = "fffffffff"}
};
output.Content = suggestionListBox.SelectedIndex.ToString();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
nameTextBox.Focus();
}
private void nameTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down)
{
suggestionListBox.Focus();
}
if (e.Key == Key.Up)
{
var listBoxItem = (ListBoxItem)suggestionListBox
.ItemContainerGenerator
.ContainerFromIndex(suggestionListBox.Items.Count - 1);
var result = listBoxItem.Focus();
}
}
private void suggestionListBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if ( (e.Key == Key.Up && suggestionListBox.SelectedIndex == 0)
|| (e.Key == Key.Down && suggestionListBox.SelectedIndex == suggestionListBox.Items.Count - 1))
{
suggestionListBox.SelectedIndex = NOT_SELECTED;
nameTextBox.Focus();
}
}
private void suggestionListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
output.Content = suggestionListBox.SelectedIndex.ToString();
}
}
}
Я попытался использовать выбранный индекс в списке, но когда я вызываю метод фокуса в списке, выбранный индекс устанавливается равным нулю. Вот почему я нахожу последний элемент списка в списке предложений и применяю к нему фокус, но он выделяет тот, что выше. Надеюсь, это имеет смысл. Чтобы продемонстрировать проблему, просто создайте новый проект WPF, скопируйте и вставьте приведенный выше код в файлы MainWindow.xaml и MainWindow.Xaml.cs и запустите приложение. Все должно быть раскрыто.
Любая помощь или указание будут приняты.
С наилучшими пожеланиями
Мохаммад.