VB.NET中多TextBox过滤DataGridView时BindingList状态异常问题
多TextBox过滤DataGridView失效问题分析与修复
问题根源
你的代码中,两个TextBox的TextChanged事件是独立处理过滤的:每次只基于原始的_criteriasBindingList进行单一条件过滤,没有同时结合两个TextBox的当前条件。例如:
- 当你在
txtcriteria1输入"A",再在txtcriteria2输入"C",此时显示的是符合Criteria2含"C"的项; - 但清空
txtcriteria2时,代码直接将数据源恢复为原始的_criteriasBindingList,完全忽略了txtcriteria1中"A"的过滤条件,导致结果不符合预期。
解决方案
将过滤逻辑抽为一个公共方法,每次任何一个TextBox内容变化时,同时读取两个条件并组合过滤原始数据,最后将结果转换为SortableBindingList绑定到BindingSource。
修改后的Form4代码
Public Class Form4 Private StockCardsCache As List(Of StockCards) Private _criteriasBindingList As New SortableBindingList(Of StockCards)() Private bindingSource As BindingSource = Nothing Private Sub LoadData() StockCardsCache = New List(Of StockCards) From { New StockCards() With { .Invono = "PI0001", .InvoDate = New DateTime(2024, 2, 1), .Transaction = "PURCHASE", .CodeProduct = "TEST 1000", .Barcode = "1000", .Criteria1 = "A", .Criteria2 = "C", .Criteria3 = "E", .Criteria4 = "G", .IN = 10, .OUT = 0, .BLC = 10 }, New StockCards() With { .Invono = "PI0001", .InvoDate = New DateTime(2024, 2, 1), .Transaction = "PURCHASE", .CodeProduct = "TEST 1000", .Barcode = "1000", .Criteria1 = "B", .Criteria2 = "D", .Criteria3 = "F", .Criteria4 = "H", .IN = 12, .OUT = 0, .BLC = 22 }, New StockCards() With { .Invono = "PI0001", .InvoDate = New DateTime(2024, 2, 1), .Transaction = "PURCHASE", .CodeProduct = "TEST 1000", .Barcode = "1000", .Criteria1 = "A", .Criteria2 = "E", .Criteria3 = "G", .Criteria4 = "I", .IN = 12, .OUT = 0, .BLC = 34 }, New StockCards() With { .Invono = "PI0001", .InvoDate = New DateTime(2024, 2, 1), .Transaction = "PURCHASE", .CodeProduct = "TEST 1000", .Barcode = "1000", .Criteria1 = "B", .Criteria2 = "F", .Criteria3 = "H", .Criteria4 = "J", .IN = 12, .OUT = 0, .BLC = 46 } } _criteriasBindingList = New SortableBindingList(Of StockCards)(StockCardsCache) bindingSource = New BindingSource With {.DataSource = _criteriasBindingList} DataGridView1.DataSource = bindingSource End Sub Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load LoadData() End Sub Private Sub txtcriteria1_TextChanged(sender As Object, e As EventArgs) Handles txtcriteria1.TextChanged FilterData() End Sub Private Sub txtcriteria2_TextChanged(sender As Object, e As EventArgs) Handles txtcriteria2.TextChanged FilterData() End Sub Private Sub FilterData() ' 获取两个TextBox的当前过滤条件 Dim criteria1 = txtcriteria1.Text.Trim().ToLower() Dim criteria2 = txtcriteria2.Text.Trim().ToLower() ' 从原始缓存数据开始组合过滤 Dim filteredData = StockCardsCache.AsEnumerable() ' 应用Criteria1过滤(仅当条件非空时) If Not String.IsNullOrEmpty(criteria1) Then filteredData = filteredData.Where(Function(c) c.Criteria1.ToLower().Contains(criteria1)) End If ' 应用Criteria2过滤(仅当条件非空时) If Not String.IsNullOrEmpty(criteria2) Then filteredData = filteredData.Where(Function(c) c.Criteria2.ToLower().Contains(criteria2)) End If ' 将过滤结果转换为SortableBindingList,保留排序支持 bindingSource.DataSource = New SortableBindingList(Of StockCards)(filteredData.ToList()) End Sub End Class
关键改进点
- 基于原始数据过滤:每次过滤都从
StockCardsCache(原始数据缓存)开始,避免多次过滤导致的条件叠加错误; - 组合多条件:同时判断两个TextBox的内容,仅当条件非空时才应用对应的过滤规则;
- 保留排序功能:将过滤后的列表转换为
SortableBindingList,保证DataGridView仍然支持排序操作。
效果演示

内容的提问来源于stack exchange,提问作者user22579796
相关产品推荐
相关产品推荐

