WPF 可搜索组合框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44764394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 14:06:36  来源:igfitidea点击:

WPF searchable combobox

wpfcomboboxfocusitems

提问by LoPeZ

I've got a ComboBoxas follows:

我有一个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>

When Cb_OnPreviewTextInputis called I set IsDropdownOpen = true. In the first attempt (after typing the first letter) the first item on the list is selected and I can go up and down using relevant arrows, the caret is still in the TextBox.

什么时候Cb_OnPreviewTextInput叫我设置IsDropdownOpen = true。在第一次尝试中(键入第一个字母后),选择了列表中的第一项,我可以使用相关箭头上下移动,插入符号仍在TextBox.

When I keep on typing at that point, I',m not able to navigate up and down (1 item at time) anymore, at this point the whole ScrollViewer gets focus and I can only go to the bottom or to the top, but not 1 by 1. I have to close the popup e.g. by pressing Escape and then reopen by typing 1 character to be able to go up/down again.

当我在那时继续打字时,我不能再上下导航(一次 1 个项目),此时整个 ScrollViewer 获得焦点,我只能转到底部或顶部,但是不是 1 个 1。我必须关闭弹出窗口,例如按 Escape,然后通过键入 1 个字符重新打开,以便能够再次向上/向下。

I also noticed that after pressing PageUp the first item gets selected as well, so I tried to mimic that in code, but no luck.

我还注意到按下 PageUp 后,第一个项目也被选中,所以我试图在代码中模仿它,但没有运气。

Anyone knows what to do here to be able to navigate up/down and type without problems?

任何人都知道在这里做什么才能毫无问题地向上/向下导航和输入?

回答by Zozo

When I have tried to reproduce your issue in isolated environment, everything seams to be fine...

当我试图在孤立的环境中重现您的问题时,一切都很好......

enter image description here

在此处输入图片说明

Which .NET version are you using?

您使用的是哪个 .NET 版本?

I have used code like this:

我使用过这样的代码:

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

and code behind looks like this

后面的代码看起来像这样

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;
}