WPF,组合框,在类型上显示候选人,但不是自动完成?

Posted

技术标签:

【中文标题】WPF,组合框,在类型上显示候选人,但不是自动完成?【英文标题】:WPF, ComboBox, Show candidates on type, but not auto-complete? 【发布时间】:2021-10-22 04:27:26 【问题描述】:

是否可以让 WPF 组合框在下面显示候选人,例如 Google 建议的工作方式,但不能自动完成输入字段上的其余文本?

例如,如果我在底部的 WPF 代码中键入“b”,我会得到这个。

但这会导致使用文本组合的亚洲语言 IME 出现一些问题。此外,这不会显示以“b”开头的所有其他候选者。相反,我可以让 WPF ComboBox 像这样显示,并让用户像大多数 IDE 文本编辑器一样使用箭头键和选项卡选择候选对象吗?

    <ComboBox HorizontalAlignment="Left" Margin="111,61,0,0" VerticalAlignment="Top" Width="120" IsEditable="True">
        <ComboBoxItem Content="Alice"/>
        <ComboBoxItem Content="Bob"/>
        <ComboBoxItem Content="Bart"/>
        <ComboBoxItem Content="Bort"/>
        <ComboBoxItem Content="Charlie"/>
    </ComboBox>

【问题讨论】:

【参考方案1】:

可以根据输入的文本对 ItemsSource 集合中的项目进行过滤。 但是,在我看来,不可能更改第一个合适的自动选择 - 这种行为嵌套在 ComboBox 逻辑中。 并且不可能将用户输入与第一个元素的文本区分开来。 因此,过滤也无法正确配置。 如果不更改 ComboBox 模板或将其替换为您自己的自定义元素,在我看来,这是不可能实现的。

基于 Expander 的实现示例:

首先,切勿使用 UI 项填充 ComboBox、ListBox(和其他 ItemsControl)。 创建一个可观察的集合并将其传递给 ItemsSource。

其次,获取此集合的表示形式,并在其 Filter 属性中设置过滤元素的处理方法。 它应该将传递给 ItemsSource 的集合元素与指定过滤器模板的 Text 值进行比较。 如果 Text 为空(string.IsNullOrWhiteSpace (Text) = true),则过滤器应跳过所有元素。

第三,当Text发生变化时,在collection view上调用Refrech。

<Window x:Class="FilterComboBox.FilterComboBoxWindow"
        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"
        xmlns:local="clr-namespace:FilterComboBox"
        mc:Ignorable="d"
        Title="FilterComboBoxWindow" Height="450" Width="800">
    <Grid x:Name="grid">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Expander>
            <Expander.Header>
                <TextBox x:Name="tBox" MinWidth="100"
                         TextChanged="OnTextChanged"/>
            </Expander.Header>
            <ListBox x:Name="listBox" SelectionChanged="OnSelectionChanged"/>
            <Expander.Style>
                <Style TargetType="Expander">
                    <Style.Triggers>
                        <Trigger Property="IsKeyboardFocusWithin" Value="True">
                            <Setter Property="IsExpanded" Value="True"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Expander.Style>

        </Expander>
        <TextBlock Grid.Row="1" Text="Binding SelectedItem, ElementName=listBox"/>
    </Grid>
</Window>
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace FilterComboBox

    /// <summary>
    /// Логика взаимодействия для FilterComboBoxWindow.xaml
    /// </summary>
    public partial class FilterComboBoxWindow : Window
    
        private readonly ObservableCollection<string> contetnItems
            = new ObservableCollection<string>()
            
                "Alice",
                "Bob",
                "Bart",
                "Bort",
                "Charlie"
            ;

        public FilterComboBoxWindow()
        
            InitializeComponent();

            ICollectionView view = CollectionViewSource.GetDefaultView(contetnItems);
            view.Filter = OnFilter;
            listBox.ItemsSource = contetnItems;
        



        private bool OnFilter(object obj)
        
            return
                string.IsNullOrWhiteSpace(tBox.Text) ||
                ((obj is string text) && text.ToUpper().StartsWith(tBox.Text.ToUpper()));
        

        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        
            tBox.Text = listBox.SelectedItem?.ToString();
        

        private void OnTextChanged(object sender, TextChangedEventArgs e)
        
            CollectionViewSource.GetDefaultView(contetnItems).Refresh();
        
    

P.S.其中大部分使用 MVVM 模式更方便、更正确。

【讨论】:

以上是关于WPF,组合框,在类型上显示候选人,但不是自动完成?的主要内容,如果未能解决你的问题,请参考以下文章

C# WPF - 组合框

组合框中的 WPF 数据绑定彩色项目

在WPF中的组合框中显示MySQL数据库的列?我只显示'System.Data.DataRowView'

WPF组合框值和显示文本

在 WPF 数据网格、组合框模板列上单击编辑

WPF DataGrid 带有一键组合框,显示按枚举名称排序的枚举值