如何使用字符串列表作为键在DataGridView中查找行?
解决方案
错误原因
你代码里的问题在于List(Of String).ForEach是无返回值的方法,它仅用于遍历列表执行指定操作,不能作为Where子句的判断条件,因此编译器会提示“表达式无返回值”。
正确实现方式
改用List(Of String).All方法替代ForEach,All会检查列表中所有元素是否都满足指定条件,返回布尔值,完全符合Where的判断需求:
Me.key = New List(Of String) From {"Key1", "Key2"} Dim row As DataGridViewRow = Nothing ' 正确写法:用All判断所有键对应的单元格值都匹配 row = (From r In Me.grid.Rows.Cast(Of DataGridViewRow)() Where Not r.IsNewRow AndAlso ' 排除DataGridView的默认新行(若启用允许添加行) Me.key.All(Function(subkey) ' 处理值为Nothing的情况,避免空引用异常 Dim val1 = r.Cells(subkey).Value Dim val2 = rowFromAnotherGrid.Cells(subkey).Value Return Object.Equals(val1, val2) End Function) Select r).FirstOrDefault()
注意点
- 加上
Not r.IsNewRow:如果你的DataGridView允许用户添加新行,默认会存在一行空的新行,需要排除它以避免匹配到无效行。 - 用
Object.Equals替代直接=:可以安全处理值为Nothing的情况,避免空引用异常。 - 调用
Cast(Of DataGridViewRow)():因为DataGridView.Rows返回的是DataGridViewRowCollection(非泛型集合),需要转换后才能使用LINQ的Where、FirstOrDefault等方法。
更优解决方案(性能优化)
如果需要多次执行匹配操作,或DataGridView行数较多,可以提前把rowFromAnotherGrid的键值对存入字典,减少重复访问Cells的开销:
Me.key = New List(Of String) From {"Key1", "Key2"} Dim row As DataGridViewRow = Nothing ' 提前缓存目标行的键值对 Dim targetKeyValues = Me.key.ToDictionary(Function(subkey) subkey, Function(subkey) rowFromAnotherGrid.Cells(subkey).Value) row = (From r In Me.grid.Rows.Cast(Of DataGridViewRow)() Where Not r.IsNewRow AndAlso Me.key.All(Function(subkey) Dim currentVal = r.Cells(subkey).Value Dim targetVal = targetKeyValues(subkey) Return Object.Equals(currentVal, targetVal) End Function) Select r).FirstOrDefault()
这种方式在键列表较长时,性能提升会更明显,因为无需重复从rowFromAnotherGrid.Cells中取值。
内容的提问来源于stack exchange,提问作者okkko
相关产品推荐
相关产品推荐

