You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何隐藏DataGridView中与Access.Text标签不匹配的行?现有代码异常

解决DataGridView筛选时全部行被隐藏的问题

你现在遇到的问题是每次文本框内容变化后所有行都被隐藏,核心原因是你的代码只处理了不匹配行的隐藏操作,却没有把之前被隐藏的、现在可能匹配的行重新设置为可见状态。另外还有个潜在坑:如果单元格值是DBNull,直接调用ToString()会抛出空引用异常。

问题拆解

  • 第一次筛选时,你隐藏了不匹配的行;但当你修改文本框内容后,之前被隐藏的行(不管现在是否匹配新文本)都没有被重置可见性,导致旧的隐藏状态叠加新的隐藏操作,最终所有行都被藏起来了
  • 未处理单元格值为空的情况,会引发运行时错误

修正后的代码

private void Access_TextChanged(object sender, EventArgs e)
{
    BindingContext[productionBindingSource].SuspendBinding();
    
    string filterText = Access.Text.Trim(); // 去掉首尾空格,避免不必要的匹配失败
    
    foreach (DataGridViewRow row in this.productionDGV.Rows)
    {
        // 跳过DataGridView自动生成的新行(如果开启了允许添加新行的功能)
        if (row.IsNewRow) continue;
        
        string cellValue = string.Empty;
        // 处理单元格值为DBNull的情况,防止报错
        if (row.Cells[4].Value != DBNull.Value)
        {
            cellValue = row.Cells[4].Value.ToString().Trim();
        }
        
        // 双向判断:匹配就显示,不匹配就隐藏,覆盖之前的状态
        row.Visible = cellValue.Equals(filterText, StringComparison.OrdinalIgnoreCase);
        // 如果需要严格区分大小写,把上面的判断改成 cellValue == filterText 即可
    }
    
    BindingContext[productionBindingSource].ResumeBinding();
}

更高效的替代方案

如果你的数据源是DataTable,其实更推荐直接用BindingSource.Filter属性来实现筛选,这种方式不需要手动遍历行,性能更好(数据量大时差距明显),代码也更简洁:

private void Access_TextChanged(object sender, EventArgs e)
{
    string filterText = Access.Text.Trim();
    if (string.IsNullOrEmpty(filterText))
    {
        // 清空筛选,显示所有行
        productionBindingSource.Filter = string.Empty;
    }
    else
    {
        // 把下面的"TargetColumnName"替换成你的DataTable中对应列的真实名称
        // 处理单引号转义,避免SQL语法错误
        string safeFilterText = filterText.Replace("'", "''");
        productionBindingSource.Filter = $"TargetColumnName = '{safeFilterText}'";
    }
}

内容的提问来源于stack exchange,提问作者Linda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:39:33