关于WPF中ComboBox文本查询功能
一种方法是使用事件(包括MVVM的绑定)
<ComboBox TextBoxBase.TextChanged="ComboBox_TextChanged" />
然而运行时就会发现,这个事件在疯狂的触发,很频繁
在实际应用中,如果关联查询数据库,网络吞吐什么的,就会卡顿
另一种方法是使用IsTextSearchEnabled属性,在文本框敲键盘会自动选择相关项
<ComboBox IsTextSearchEnabled="True" IsTextSearchCaseSensitive="False" TextSearch.TextPath="Name" />
然而又有新的问题,选择项不会显示到文本框(文本框仍然是键盘敲的内容,当然还可能跟Framework版本有关),于是我们需要更深入
试验数据含 3 个项
<ComboBox TextBoxBase.TextChanged="ComboBox_TextChanged"><ComboBoxItem>啊啊啊</ComboBoxItem><ComboBoxItem>哦哦哦</ComboBoxItem><ComboBoxItem>呃呃呃</ComboBoxItem></ComboBox>

试验一:绑定 TextChanged 和 SelectionChanged 调试
private void Combobox_TextChanged(object sender, TextChangedEventArgs e){// e.OriginalSource == TextBox, e.Source == sender == Comboboxvar tb = e.OriginalSource as TextBox;var cb = e.Source as ComboBox;var cs = e.Changes.ToArray();int alen = -1, offs = -1, rlen = -1;if (cs.Length > 0) { alen = cs[0].AddedLength; offs = cs[0].Offset; rlen = cs[0].RemovedLength; }var str1 = TextSearch.GetText(cmbStudios);System.Diagnostics.Debug.Print($"TextBox.Text={tb.Text},ComboBox.Text={cb.Text},TextSearch.Text={str1},Action={e.UndoAction}, Changes={cs.Length}: [0]={{{alen},{offs},{rlen}}}\r\n");}private void Combobox_SelectionChanged(object sender, SelectionChangedEventArgs e){var cb = e.Source as ComboBox;System.Diagnostics.Debug.Print($"ComboBox.Text={cb.Text},SelectedItem={cb.SelectedItem}\r\n");}
记录
TextBox.Text=a,ComboBox.Text=,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,0}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=None, Changes=0: [0]={-1,-1,-1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
ComboBox.Text=啊,SelectedItem=啊啊啊
TextBox.Text=啊啊啊,ComboBox.Text=啊啊啊,TextSearch.Text=,Action=Create, Changes=1: [0]={3,0,1}
也就是选择项目正常设置Text属性,但是现在我们要让Text改变自动选择项目
试验二:启用IsTextSearchEnabled属性
TextBox.Text=a,ComboBox.Text=,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,0}
ComboBox.Text=,SelectedItem=啊啊啊
TextBox.Text=啊,ComboBox.Text=啊啊啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=None, Changes=0: [0]={-1,-1,-1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
敲a一次,空格变成“啊”自动选择“啊啊啊”项目,然后就开始抽,完全看不到适当的介入时机
用过Win10的都知道,文件夹右上角的搜索框,能在输入法完成后才开始搜索,所以一定是可以实现的
换网,查英文资料发现Win11中有TextCompositionEnded事件,但是WPF中找不到,类似的TextCompositionManager外挂

实验三:启用TextComposition事件
<TextBox TextCompositionManager.TextInputStart="TextBox_TextInputStart" TextCompositionManager.TextInputUpdate="TextBox_TextInputUpdate" TextCompositionManager.TextInput="TextBox_TextInput" />
事件响应代码
private void TextBox_TextInputStart(object sender, TextCompositionEventArgs e){var tc = e.TextComposition;string text = $" CompositionText={tc.CompositionText},ControlText={tc.ControlText},ControlText={tc.SystemText},Text={tc.Text} ";System.Diagnostics.Debug.Print($"TextInputStart() ControlText={e.ControlText},SystemText={e.SystemText},Text={e.Text},TextComposition={{{text}}}\r\n");}private void TextBox_TextInputUpdate(object sender, TextCompositionEventArgs e){var tc = e.TextComposition;string text = $" CompositionText={tc.CompositionText},ControlText={tc.ControlText},ControlText={tc.SystemText},Text={tc.Text} ";System.Diagnostics.Debug.Print($"TextInputUpdate() ControlText={e.ControlText},SystemText={e.SystemText},Text={e.Text},TextComposition={{{text}}}\r\n");}private void TextBox_TextInput(object sender, TextCompositionEventArgs e){var tc = e.TextComposition;string text = $" CompositionText={tc.CompositionText},ControlText={tc.ControlText},ControlText={tc.SystemText},Text={tc.Text} ";System.Diagnostics.Debug.Print($"TextInput() ControlText={e.ControlText},SystemText={e.SystemText},Text={e.Text},TextComposition={{{text}}}\r\n");}
记录
TextInputStart() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=a,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=啊,ControlText=,ControlText=,Text= }
没有TextInput事件!
英文资料显示,会依次触发 TextCompositionStarted、TextChanging、TextChanged、TextCompositionChanged、TextCompositionEnded 事件
思考是隧道事件的问题:
如上面提到的外挂,WPF中的控件其实都外挂的,而且还可以自己给现有的类添加属性、方法和事件(参考:Binding Property)
由于可以任意的排布所有的控件,因此事件的响应与传统的MFC控件就开始有差异

如图,如果鼠标点在2上,传统的事件会由2响应,容器1对此一无所知
这有什么问题?有没有问题就看你怎么看问题。
所谓路由事件是把响应规则扩展为3类:
1.直接事件:等同传统事件
2.冒泡事件:从內向外依次触发,直到Handled被设置
3.隧道事件:从外向内依次触发,直到Handled被设置,这样容器就有机会在内部控件之前做出响应,事件一般以Preview开头,常见的如多个带滚动条的控件互相包含
试验四:加入Preview事件
PreviewTextInputStart() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=,ControlText=,ControlText=,Text= }
TextInputStart() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=,ControlText=,ControlText=,Text= }
PreviewTextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=a,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=a,ControlText=,ControlText=,Text= }
PreviewTextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=啊,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=啊,ControlText=,ControlText=,Text= }
PreviewTextInput() ControlText=,SystemText=,Text=啊,TextComposition={ CompositionText=,ControlText=,ControlText=,Text=啊 }
所有的都可以不管,只看PreviewTextInput检查Text属性就是输入法敲出完整的文本时
策略响应的也就简单了
1.加入一个Timer
2.在TextInput事件启动计时器,其它如Start和Update时停止计时器
3.计时器响应执行过滤逻辑,然后停止计时器
当然这是Windows文件搜索框的逻辑,也就是你敲键盘很快的话,中途不会执行搜索,你也可以根据需要进行调整,比如Start也开始计时器,如果Update过一段时间未触发,一样执行逻辑
相关文章:
关于WPF中ComboBox文本查询功能
一种方法是使用事件(包括MVVM的绑定) <ComboBox TextBoxBase.TextChanged"ComboBox_TextChanged" /> 然而运行时就会发现,这个事件在疯狂的触发,很频繁 在实际应用中,如果关联查询数据库࿰…...
解析“in the wild”——编程和生活中的俚语妙用
解析“in the wild”——编程和生活中的俚语妙用 看下面的技术文章中遇到 in the wild这个词,想要研究一下,遂产生此文。 Are there ever pointers to pointers to pointers? There is an old programming joke which says you can rate C programmers…...
蓝桥杯练习日常|c/c++竞赛常用库函数(下)
书接上回......蓝桥杯算法日常|c\c常用竞赛函数总结备用-CSDN博客 目录 书接上回......https://blog.csdn.net/weixin_47011416/article/details/145290017 1、二分查找 2、lower_bound uper_bound 3、memset() 函数原型 参数说明 返回值 常见用…...
Mybatis-plus缓存
mybatis-plus缓存 MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上提供了更多的便利性和强大的功能,包括但不限于分页、条件构造器、通用 Mapper、代码生成器等。MyBatis-Plus 也内置了基础的缓存功能,但需要注意的是ÿ…...
LockSupport概述、阻塞方法park、唤醒方法unpark(thread)、解决的痛点、带来的面试题
目录 ①. 什么是LockSupport? ②. 阻塞方法 ③. 唤醒方法(注意这个permit最多只能为1) ④. LockSupport它的解决的痛点 ⑤. LockSupport 面试题目 ①. 什么是LockSupport? ①. 通过park()和unpark(thread)方法来实现阻塞和唤醒线程的操作 ②. LockSupport是一个线程阻塞…...
基于 WPF 平台使用纯 C# 实现动态处理 json 字符串
一、引言 在当今的软件开发领域,数据的交换与存储变得愈发频繁,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,以其简洁、易读、便于解析和生成的特点,被广泛应用于各种应用程序中。在 W…...
Rust:Rhai脚本编程示例
当然,以下是一个简单的Rhai脚本编程示例,展示了如何在Rust中使用Rhai执行脚本。 首先,你需要确保你的Rust项目中包含了rhai库。你可以在你的Cargo.toml文件中添加以下依赖项: [dependencies] rhai "0.19" # 请检查最…...
skynet 源码阅读 -- 启动主流程
Skynet 启动主流程分析 Skynet 是一个轻量级、高并发的服务器框架。它在启动时会进行一系列初始化操作,并启动多个不同功能的线程(Monitor、Timer、Worker、Socket),从而实现消息分发、定时器、网络I/O等核心功能。本文主要从 ma…...
活动回顾和预告|微软开发者社区 Code Without Barriers 上海站首场活动成功举办!
Code Without Barriers 上海活动回顾 Code Without Barriers:AI & DATA 深入探索人工智能与数据如何变革行业 2025年1月16日,微软开发者社区 Code Without Barriers (CWB)携手 She Rewires 她原力在大中华区的首场活动“AI &…...
Workerman和Swoole有什么区别
Workerman和Swoole都是PHP的socket服务器框架,它们之间存在一些显著的区别,主要体现在以下几个方面: 一、实现语言与性能 Workerman:使用纯PHP实现。由于PHP本身的性能限制,Workerman在某些方面可能不如C语言实现的框…...
项目部署(springboot项目)
1、安装Nginx,并开启 2、前端项目打包:npm run build:prod--->dist 3、后端项目打包:install--->xxx.jar 4、开放需要的端口号:比如我的后端项目端口号为8282,则需要防火墙和服务器同时开发8282端口 5、将di…...
从0到1:C++ 开启游戏开发奇幻之旅(一)
目录 为什么选择 C 进行游戏开发 性能卓越 内存管理精细 跨平台兼容性强 搭建 C 游戏开发环境 集成开发环境(IDE) Visual Studio CLion 图形库 SDL(Simple DirectMedia Layer) SFML(Simple and Fast Multim…...
Python-列表
3.1 列表是什么 在Python中,列表是一种非常重要的数据结构,用于存储一系列有序的元素。列表中的每个元素都有一个索引,索引从0开始。列表可以包含任何类型的元素,包括其他列表。 # 创建一个列表my_list [1, 2, 3, four, 5.0]…...
下载Visual Studio Community 2019
官方链接如下:Visual Studio Community 2019下载链接 https://learn.microsoft.com/zh-cn/visualstudio/releases/2019/system-requirements#download 目前官方仅建议2022版,已经关闭vs2019等旧版本,哪天开放了,记得踢我一下。 …...
MongoDB平替数据库对比
背景 项目一直是与实时在线监测相关,特点数据量大,读写操作大,所以选用的是MongoDB。但按趋势来讲,需要有一款国产数据库可替代,实现信创要求。选型对比如下 1. IoTDB 这款是由清华大学主导的开源时序数据库&#x…...
c++ set/multiset 容器
1. set 基本概念 简介: 所有元素都会在插入时自动排序本质: set/multiset属于关联式容器,底层结构是用二叉树实现。set 和 multiset 区别: set容器不允许有重复的元素。 multiset允许有重复的元素。2. set 构造和赋值 构造&a…...
SCRM在企业私域流量与客户管理中的变革之路探索
内容概要 在当今数字化高速发展的时代,SCRM(社交客户关系管理)作为一种新的管理工具,正逐渐成为企业私域流量管理和客户关系维护的重要基石。它不仅仅是一种软件工具,更是一种整合客户数据和关系管理的全新思维方式。…...
爱的魔力转圈圈,基于carsim与simulink模拟仰望u8原地调头
仰望U8原地转向的示意图如下,不动方向盘的情况下,车可以自己转圈圈: 原理也很简单,仰望u8是四轮驱动,四个轮子都单独由四个轮边电机驱动。主要我们将左右的车轮轮速控制成左右两边轮速相同,但是方向相反&am…...
2025多目标优化创新路径汇总
多目标优化是当下非常热门且有前景的方向!作为AI领域的核心技术之一,其专注于解决多个相互冲突的目标的协同优化问题,核心理念是寻找一组“不完美但均衡”的“帕累托最优解”。在实际中,几乎处处都有它的身影。 但随着需求场景的…...
输出九九乘法表
# 题目:输出九九乘法表 #(1) for i in range(1,10): #行数,1到9for j in range(1,10): # 列数1到9resulti*jprint(f"{i}*{j}{result}",end"\t")print("\n")#(2) for i in range(1,10): #行数for j in range(1,i1): #列数1…...
基于微信小程序的新闻资讯系统设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
vim如何解决‘’文件非法关闭后,遗留交换文件‘’的问题
过程描述: 由于我修改文件时(一定得修改了文件,不做任何修改不会产生这个问题)的非法关闭,比如直接关闭虚拟机,或者直接断开远程工具的远程连接,产生了以下遗留交换文件的问题: 点击…...
vue3+elementPlus之后台管理系统(从0到1)(day4-完结)
面包屑 创建一个面包屑组件 将路由导入然后格式化map对象 key-value 将当前路由的key和value获取然后存入list数组中 遍历list数据,渲染内容 <!--BreadcrumbCom.vue--> <template><el-breadcrumb separator">"><el-breadcrum…...
基于Flask的旅游系统的设计与实现
【Flask】基于Flask的旅游系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为后端开发语言,结合前端Bootstrap框架,为用户提供了丰富…...
代码随想录31
目录 leetcode135.分发糖果 思路: leetcode860.柠檬水找零 思路:就是一个个遍历然后判断,用哈希表存储数。 leetcode406.根据身高重建队列 leetcode135.分发糖果 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需…...
【公因数匹配——暴力、(质)因数分解、哈希】
题目 暴力代码,Acwing 8/10,官网AC #include <bits/stdc.h> using namespace std; const int N 1e610; vector<int> nums[N]; int main() {ios::sync_with_stdio(0);cin.tie(0);int n;cin >> n;for(int i 1; i < n; i){int x;ci…...
WPS数据分析000010
基于数据透视表的内容 一、排序 手动调动 二、筛选 三、值显示方式 四、值汇总依据 五、布局和选项 不显示分类汇总 合并居中带标签的单元格 空单元格显示 六、显示报表筛选页...
RabbitMQ 架构分析
文章目录 前言一、RabbitMQ架构分析1、Broker2、Vhost3、Producer4、Messages5、Connections6、Channel7、Exchange7、Queue8、Consumer 二、消息路由机制1、Direct Exchange2、Topic Exchange3、Fanout Exchange4、Headers Exchange5、notice5.1、备用交换机(Alter…...
127周一复盘 (165)玩法与难度思考
1.上午测试,小改了点东西, 基本等于啥也没干。 匆忙赶往车站。 从此进入春节期间,没有开发,而思考与设计。 2.火车上思考玩法与难度的问题。 目前的主流作法实际上并不完全符合不同玩家的需求, 对这方面还是要有自…...
Spring--SpringMVC使用(接收和响应数据、RESTFul风格设计、其他扩展)
SpringMVC使用 二.SpringMVC接收数据2.1访问路径设置2.2接收参数1.param和json2.param接收数据3 路径 参数接收4.json参数接收 2.3接收cookie数据2.4接收请求头数据2.5原生api获取2.6共享域对象 三.SringMVC响应数据3.1返回json数据ResponseBodyRestController 3.2返回静态资源…...
