为DataGridView中的DataGridViewComboBoxCell添加SelectedIndexChanged事件

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43145361/article/details/100111840

简介

DataGridView 是一个非常强大的数据控件,能够以类似Excel的方式处理二维数据。并且针对数据的不同格式,能够为数据添加对应的编辑控件,如下拉框DataGridViewComboBoxCell。但是由于这些扩展的单元格和原生的控件有一定区别,所以在使用的时候,有不一样的地方需要注意。

问题

虽然DataGridViewComboBoxCell能够象ComboBox一样显示下拉框,但是却中没有 SelectedIndexChanged事件,这给使用带来了非常多的不便。经研究发现,很多文章都给出了方案,即利用 DataGridView 的 EditingControlShowing 事件。然而,这些代码没有告诉你的是,由于每次弹出控件时都会触发这个事件,所以事件关联会被多次添加而导致多次触发。

解决方案

由于在每个控件中都有一个Tag属性,所以我们可以利用它来进行验证。当事件发生时,我们判断其Tag是否为空,如果为空则还没有添加事件,如果为不空则已经添加了不再处理。而在添加事件代码后,我们要为其Tag赋任意值,比如1。

具体实现代码如下所示:

private void dgv_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    if (dgv.CurrentCell is DataGridViewComboBoxCell comboCell && e.Control is ComboBox cb)
    {
	    // 通过Tag保证SelectedIndexChanged事件只关联一次。
	    if (cb.Tag == null) 
	    {
	        cb.SelectedIndexChanged += (sender1, e1) => Console.WriteLine(cb.Text);
	        cb.Tag = 1; // 关联好事件后将Tag置为1,从而避免下次还添加。
	    }
	}
}

方法扩展

其实解决的办法有很多种,以上只是提供了一个简单的思路。这种方式还有个副作用就是Tag不能被其他程序占用。一般情况下,DataGridViewComboBoxCell中的ComboBox的Tag属性是不会被占用的,不过如果遇到特殊情况被占用了,以上的方法就无用了。所以这里再提供其他几种解决思路:

  • 调用时取消事件关联
    在dgv_SelectedIndexChanged 的事件函数中,执行以下类似代码:
    cb.SelectedIndexChanged -= new EventHandler(cb_SelectedIndexChanged);
    从而在SelectedIndexChanged事件发生过程中,取消事件的绑定。这样每次调用时绑定,执行后取消绑定,也可以解决问题。
  • 全局ComboBox列表记录
    我们也可以建立一个全局的 List<ComboBox> 列表,每次注册完SelectedIndexChanged事件以后,就将此ComboBox添加到此列表中,然后每次在注册事件前,检测要注册事件的ComboBox是否在此列表中即可。

猜你喜欢

转载自blog.csdn.net/weixin_43145361/article/details/100111840