2024年3月26日发(作者:)

WPF基于ComboBox实现(花里胡

哨)搜索功能与占位符提示

目标

首先,网上还有很多更高级的方式来实现题目中描述的功能,

比如自定义样式,自定义控件(应该叫那个)。在这里,我只记

录我的个人经历。毕竟花了很长时间才明白其中的一些原理。

一、实现搜索功能

ComboBox本身已经具备搜索功能,只需要将其IsEditable和

IsTextSearchEnable开关打开就可以了。但是这个搜索功能

是比较简单的,它能够帮你定位到第一个(如果有的话)匹配

项。我想实现的是根据搜索文字更新列表内容,理由是这样更

加酷炫。下面是实现方法(和一些坑)。

1. ComboBox定义

首先!我们需要关闭IsTextSearchEnable,理由是:它不仅

帮我们定位匹配项,同时还会将SelectedItem也设置成这一

项,这样会给我们的代码带来逻辑混乱。具体解释如下:

从属性角度来看,ComboBox的SelectedIndex,

SelectedItem和Text的更新顺序是从前往后的,搜

索逻辑本来应该是基于Text去更新源,但是更新源

的操作会导致Selected的更新,进而再次引起Text

更新,那么逻辑就会变得未知且不可控(甚至程序行

为会出现有断点和没断点时两个样的情况)从事件的

角度来说,我观察到很奇怪的一点,即控件内部由

Selected引起的更新优先级是高于用户的输入行为

的,假如说我输入“六”,代码自动选中“六六六”

这一项并开始更新Text以及其他属性,等到这些更

新都完成了,用户输入的“六”才会开始去更新Text

(甚至会更新多次),最终导致界面显示的和代码选

中的内容不一致,而且由于逻辑上的混乱,很难在这

个情况下去解决不一致的问题。

我们所用到的ComboBox大概长这样:

Text="{Binding SearchText}"

IsEditable="True"

IsTextSearchEnable="False"/>

基于这个定义,我们将搜索逻辑放到searchText的set方法

中实现。

2. .cs代码

在.cs文件中(Model或者ViewModel都可以,如果是要将这

个ComboBox写成自定义控件的话,Model是更方便的选择,

并且后面许多功能都没法使用Binding),我们定义上面绑定

的属性如下:

privateList ItemsSource;publicList FilterItems

{get;set;}privatestring mSearchText;publicstring

SearchText

{get{return mSearchText;}set{

mSearchText=value;

FilterItems=(x=>ns(value

)).ToList();}}