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"/>

Другие вопросы по тегам