如何移除并重新添加DataGridView内TextBox的事件处理程序?
解决DataGridView OnEnter事件重复触发及内部TextBox事件重复绑定问题
问题根源
- TextBox事件重复绑定:
EditingControlShowing事件每次单元格进入编辑模式都会触发,你现在每次触发都给TextBox添加事件处理程序,导致同一个事件被绑定多次,执行时就会重复触发。 - OnEnter逻辑引发重复:自定义控件的
OnEnter方法里直接设置CurrentCell并调用BeginEdit(true),这会导致焦点切换时再次触发Enter事件,形成循环。
具体修复步骤
1. 先移除TextBox已有事件再重新添加
在customControl11_EditingControlShowing方法里,每次添加事件前先移除同名的事件处理程序,确保每次只有一个绑定:
private void customControl11_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { if (customControl11.CurrentCell.ColumnIndex == 0) { TextBox textBox = e.Control as TextBox; if (textBox != null) { // 先移除已绑定的事件,再重新添加 textBox.TextChanged -= TextBox_TextChanged; textBox.KeyDown -= TextBox_KeyDown; textBox.Enter -= TextBox_Enter; textBox.TextChanged += TextBox_TextChanged; textBox.KeyDown += TextBox_KeyDown; textBox.Enter += TextBox_Enter; } } else { // 非目标列也要移除事件,避免其他单元格的TextBox残留绑定 TextBox textBox = e.Control as TextBox; if (textBox != null) { textBox.TextChanged -= TextBox_TextChanged; textBox.KeyDown -= TextBox_KeyDown; textBox.Enter -= TextBox_Enter; } } }
2. 优化自定义控件的OnEnter方法
添加判断条件,避免重复执行设置CurrentCell和BeginEdit的逻辑:
protected override void OnEnter(EventArgs e) { base.OnEnter(e); // 只有当前单元格不是目标单元格,或未处于编辑状态时才执行 if (this.Rows.Count > 0 && (this.CurrentCell != this.Rows[0].Cells[0] || !this.IsCurrentCellInEditMode)) { this.CurrentCell = this.Rows[0].Cells[0]; this.BeginEdit(true); } }
额外注意点
- 确保
TextBox_TextChanged、TextBox_KeyDown、TextBox_Enter都是命名方法(不是匿名方法),这样才能正确移除事件绑定。 - 加
Rows.Count > 0的判断,避免DataGridView初始化无数据时出现空引用错误。
内容的提问来源于stack exchange,提问作者ankit goel
相关产品推荐
相关产品推荐

