VB.NET中基于Dapper实现ComboBox任意字符串匹配自动补全功能(Form4无法生效)
VB.NET中基于Dapper实现ComboBox任意字符串匹配自动补全功能(Form4无法生效)
你好,我仔细对比了Form1和Form4的代码,发现Form4里有几个关键问题导致自动补全功能失效,咱们逐个梳理并修正:
问题1:FilterList方法中错误的数据源处理
在Form4的FilterList方法里,你每次都重新从数据库查询数据,紧接着又调用CBFilteredList.Clear(),这直接把刚查出来的数据清空了,后续循环自然找不到任何匹配项。正确的做法应该像Form1那样,只在Form加载时从数据库加载一次完整的CBFullList,之后过滤操作直接基于这个本地字典来做,不用每次都查数据库。
问题2:DisplayMember/ValueMember的大小写不匹配
Dictionary的键值对是KeyValuePair(Of String, Integer),它的属性名是Key和Value(首字母大写),但你在Form4里写的是"key"和"value"(小写),这会导致ComboBox无法正确绑定显示和值成员,自然看不到选项。
问题3:初始化时的数据源绑定问题
Form4的BindcomboboxColorCode里直接把CBFullList.ToArray()设为数据源,和Form1的BindingSource方式不一致,虽然不是致命问题,但统一用BindingSource会更稳定。
修正后的Form4完整代码
Public Class Form4 Private bindingSource1 As BindingSource = Nothing Private connectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\dapperdemo.accdb;Persist Security Info=False;" Private CBFullList As Dictionary(Of String, Integer) Private ComboBoxBusy As Boolean Private CBFilteredList As Dictionary(Of String, Integer) Private Sub BindcomboboxColorCode() Using conn = New OleDbConnection(connectionString) conn.Open() Dim sql = "SELECT * FROM Dictionarytest" ' 一次性加载完整数据到CBFullList,后续过滤不再查库 CBFullList = conn.Query(Of Dictionarytest)(sql).ToDictionary(Function(row) row.Result, Function(row) row.Key) End Using ' 初始化ComboBox的基础配置 With ComboBox1 .DisplayMember = "Key" ' 注意首字母大写 .ValueMember = "Value" ' 注意首字母大写 .DropDownHeight = 80 .DropDownStyle = ComboBoxStyle.DropDown .AutoCompleteMode = AutoCompleteMode.None .AutoCompleteSource = AutoCompleteSource.None End With End Sub Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load ComboBoxBusy = False CBFilteredList = New Dictionary(Of String, Integer)() ' 初始化过滤字典 BindcomboboxColorCode() FilterList(False) End Sub Private Sub FilterList(ByVal show As Boolean) If ComboBoxBusy = False Then Dim orgText As String ComboBoxBusy = True orgText = ComboBox1.Text ComboBox1.DroppedDown = False CBFilteredList.Clear() ' 直接从已加载的CBFullList中过滤,不再重复查库 For Each item As KeyValuePair(Of String, Integer) In CBFullList If item.Key.ToUpper().Contains(orgText.ToUpper()) Then CBFilteredList.Add(item.Key, item.Value) End If Next item If CBFilteredList.Count < 1 Then CBFilteredList.Add("None", 0) End If ComboBox1.BeginUpdate() ' 用BindingSource绑定数据源,和Form1保持一致 ComboBox1.DataSource = New BindingSource(CBFilteredList, Nothing) ComboBox1.DisplayMember = "Key" ComboBox1.ValueMember = "Value" ComboBox1.DropDownStyle = ComboBoxStyle.DropDown ComboBox1.AutoCompleteMode = AutoCompleteMode.None ComboBox1.AutoCompleteSource = AutoCompleteSource.None ComboBox1.DroppedDown = show ComboBox1.SelectedIndex = -1 ComboBox1.Text = orgText ComboBox1.Select(ComboBox1.Text.Length, 0) ComboBox1.EndUpdate() Cursor.Current = Cursors.Default ComboBoxBusy = False End If End Sub Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged If ComboBoxBusy = False Then FilterList(False) End If End Sub Private Sub ComboBox1_TextUpdate(sender As Object, e As EventArgs) Handles ComboBox1.TextUpdate FilterList(True) End Sub End Class Public Class Dictionarytest Public Property Key() As Integer Public Property Result() As String End Class
修正要点说明
- 一次性加载数据源:在
BindcomboboxColorCode里只加载一次完整的CBFullList,FilterList中直接基于这个本地字典过滤,避免重复数据库查询,同时解决了之前清空数据的问题。 - 修正属性名大小写:把
DisplayMember和ValueMember的设置改为首字母大写的"Key"和"Value",确保ComboBox能正确识别绑定的属性。 - 统一使用BindingSource:和Form1一样用
BindingSource来绑定数据源,让控件数据绑定更稳定。 - 初始化CBFilteredList:在Form_Load中初始化
CBFilteredList,避免空引用异常。
这样修改后,Form4的ComboBox应该就能像Form1一样实现任意字符串匹配的自动补全功能了。
备注:内容来源于stack exchange,提问作者user22579796
相关产品推荐
相关产品推荐

