C# DataGridView单元格LIKE模糊匹配自动补全遇空引用异常
解决DataGridView单元格模糊匹配自动补全问题
我来帮你搞定这个DataGridView的模糊补全需求,先说说你遇到的NullReferenceException问题根源,再给你完整的实现方案。
为什么会出现空引用异常?
你之前直接用dataGridView1.Rows[currentRow].Cells[0].Value.ToString()获取输入值是错的——当单元格处于编辑状态时,用户输入的内容并没有立刻同步到Cell的Value属性里,这个属性要等编辑结束(比如单元格失去焦点)才会更新。此时实时输入的内容其实存放在当前的编辑控件(默认是TextBox)里,直接取Cell的Value自然会拿到null,触发空引用异常。
完整实现步骤&代码
我们需要通过监听DataGridView的编辑控件事件,获取实时输入文本,再实现LIKE风格的模糊匹配补全。
1. 初始化基础设置
在窗体的构造函数或者Load事件里,开启编辑模式并绑定关键事件:
public YourForm() { InitializeComponent(); // 设置单元格编辑触发方式(可根据需求调整) dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter; // 监听编辑控件加载事件,用来给TextBox绑定补全逻辑 dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing; }
2. 绑定编辑控件的补全规则
在EditingControlShowing事件里,我们要针对目标列(比如第一列,索引0)的编辑TextBox,设置自动补全模式,并监听文本变化事件:
private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { // 只给第一列设置补全,可根据你的需求修改列索引 if (dataGridView1.CurrentCell.ColumnIndex != 0) return; // 将编辑控件转换为TextBox(DataGridView默认的文本编辑控件是TextBox) if (e.Control is TextBox editTextBox) { // 先移除旧的TextChanged绑定,避免重复触发 editTextBox.TextChanged -= EditTextBox_TextChanged; // 设置补全模式:仅显示建议列表(也可以选SuggestAppend追加补全内容) editTextBox.AutoCompleteMode = AutoCompleteMode.Suggest; editTextBox.AutoCompleteSource = AutoCompleteSource.CustomSource; // 绑定文本变化事件,实时更新补全列表 editTextBox.TextChanged += EditTextBox_TextChanged; } }
3. 实现模糊匹配的补全逻辑
在TextChanged事件里,根据用户输入的文本,筛选出包含该子串的项,更新自动补全源:
// 假设你的数据源是这个集合,实际开发中可以替换成数据库查询 private List<string> productList = new List<string> { "samsung note 1", "iphone 14", "redmi note 12", "huawei mate 50" }; private void EditTextBox_TextChanged(object sender, EventArgs e) { var editTextBox = sender as TextBox; if (editTextBox == null) return; string inputText = editTextBox.Text.Trim(); var autoCompleteSource = new AutoCompleteStringCollection(); if (!string.IsNullOrEmpty(inputText)) { // 模糊匹配:筛选包含输入文本的项,忽略大小写 var matchedItems = productList.Where(item => item.IndexOf(inputText, StringComparison.OrdinalIgnoreCase) != -1).ToList(); // 如果是从数据库查询,一定要用参数化查询避免SQL注入,示例: // SELECT ProductName FROM Products WHERE ProductName LIKE '%' + @InputText + '%' // 然后把查询结果转成字符串集合 autoCompleteSource.AddRange(matchedItems.ToArray()); } else { // 输入为空时,显示所有可选项 autoCompleteSource.AddRange(productList.ToArray()); } // 更新TextBox的自动补全源 editTextBox.AutoCompleteCustomSource = autoCompleteSource; }
额外注意事项
- SQL注入防护:如果你的数据来自数据库,必须使用参数化查询,绝对不能直接拼接SQL字符串。
- 性能优化:如果数据源很大,模糊匹配可能会卡顿,可以考虑做本地缓存,或者用异步查询避免阻塞UI。
- 大小写敏感控制:示例里用了
StringComparison.OrdinalIgnoreCase实现忽略大小写匹配,如果你需要区分大小写,去掉这个参数即可。
内容的提问来源于stack exchange,提问作者user2809386
相关产品推荐
相关产品推荐

