WPF поиск комбобокс
У меня есть ComboBox
следующее:
ComboBox IsEditable="True"
Width="200"
Height="25"
IsTextSearchEnabled="False"
x:Name="cb"
PreviewTextInput="Cb_OnPreviewTextInput"
ItemsSource="{Binding ItemList}"
Text="{Binding SearchTextText}">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
когда Cb_OnPreviewTextInput
называется я поставил IsDropdownOpen = true
, В первой попытке (после ввода первой буквы) выбирается первый элемент в списке, и я могу перемещаться вверх и вниз с помощью соответствующих стрелок, каретка все еще находится в TextBox
,
Когда я продолжаю печатать в этой точке, я больше не могу перемещаться вверх и вниз (по 1 элементу за раз), в этот момент весь ScrollViewer получает фокус, и я могу переходить только вниз или вверх, но не 1 на 1. Я должен закрыть всплывающее окно, например, нажав Escape, а затем снова открыть, набрав 1 символ, чтобы иметь возможность снова идти вверх / вниз.
Я также заметил, что после нажатия PageUp первый элемент также выделяется, поэтому я попытался имитировать это в коде, но безуспешно.
Кто-нибудь знает, что здесь делать, чтобы иметь возможность перемещаться вверх / вниз и печатать без проблем?
2 ответа
Когда я попытался воспроизвести вашу проблему в изолированной среде, все выглядит хорошо...
Какую версию.NET вы используете?
Я использовал такой код:
<Window x:Class="InterviewApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<WrapPanel Orientation="Horizontal">
<ComboBox IsEditable="True"
Width="200"
Height="25"
IsTextSearchEnabled="False"
x:Name="cb"
PreviewTextInput="Cb_OnPreviewTextInput"
ItemsSource="{Binding ItemList}"
Text="{Binding SearchTextText}">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</WrapPanel>
</Window>
и код выглядит так
namespace Application
{
public partial class MainWindow : INotifyPropertyChanged
{
public MainWindow()
{
ItemList = new ObservableCollection<string>();
for (var i = 0; i < 1000; i++)
{
ItemList.Add($"Item {i}");
}
InitializeComponent();
}
private void Cb_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
cb.IsDropDownOpen = true;
}
public ObservableCollection<string> ItemList { get; set; }
public string SearchTextText
{
get => _searchTextText;
set
{
if (_searchTextText == value) return;
_searchTextText = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SearchTextText)));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
У Джорди есть лучший ответ для создания отфильтрованного ComboBox здесь: Динамический фильтр поля со списком WPF на основе ввода текста. Если вы пойдете этим путем, вы можете реализовать его в xaml:
<local:FilterableComboBox Width="250" Height="25" ItemsSource="{Binding ItemList}" SelectedItem="{Binding SelectedItem}" OnlyValuesInList="True"/>