好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

匿名委托注册事件的触发

匿名委托注册事件的触发

需求
需要在DataGridView新增行时触发新行第二列的双击事件以显示数据选择窗体,具体如下图

 

事件代码入下
 //单元格双击事件处理  

View Code

 dataGridView1.CellDoubleClick +=  (s, e) => 
            {
                  if  (e.RowIndex <  0 )  return  ;
                  var  curItem=bindingSource1.Current  as   KB_Route;
               
                  if  (e.ColumnIndex >=  0  && dataGridView1.Columns[e.ColumnIndex].Name ==  "  workStationIdColumn  "  )
                {
                      var  frm =  new   frmWorkStationSelector();
                    frm.StartPosition  =  FormStartPosition.CenterParent;
                      if  (frm.ShowDialog() ==  System.Windows.Forms.DialogResult.OK)
                    {
                          var  refEnt =  frm.RefEntity;
                          if  (curItem !=  null  )
                        {
                            curItem.WorkStationId  =  refEnt.WorkStationId;
                            curItem.WSName  =  refEnt.WSName;
                            bindingSource1.EndEdit();
                        }
                    }
                    frm.Dispose();
                }
            }; 

            dataGridView1.CellDoubleClick +=  (s, e) => 
            {
                  if  (e.RowIndex <  0 )  return  ;
                  var  curItem=bindingSource1.Current  as   KB_Route;
               
                  if  (e.ColumnIndex >=  0  && dataGridView1.Columns[e.ColumnIndex].Name ==  "  workStationIdColumn  "  )
                {
                      var  frm =  new   frmWorkStationSelector();
                    frm.StartPosition  =  FormStartPosition.CenterParent;
                      if  (frm.ShowDialog() ==  System.Windows.Forms.DialogResult.OK)
                    {
                          var  refEnt =  frm.RefEntity;
                          if  (curItem !=  null  )
                        {
                            curItem.WorkStationId  =  refEnt.WorkStationId;
                            curItem.WSName  =  refEnt.WSName;
                            bindingSource1.EndEdit();
                        }
                    }
                    frm.Dispose();
                }
            }; 

  办法一

在窗体定义个字段,定义匿名委托时顺便设置该字段,在添加新行时直接调用就完事.
在匿名委托出现之前上面的问题根本就不是问题,不过既然匿名委托可以将事件处理代码写的紧凑点,那么办法1就显的不完美.


办法二
通过反射,控件的CellDoubleClick事件是通过事件属性方式声明的,借助Reflector可以看到相关的字段定义,实现的调用代码如下

View Code

  //  反射方式调用 
                 var  ptyInfo = dataGridView1.GetType().GetProperty( "  Events  " , BindingFlags.NonPublic |  BindingFlags.Instance);
                  if  (ptyInfo !=  null  )
                {
                      var  handleList = ptyInfo.GetValue(dataGridView1,  null )  as   EventHandlerList;
                      var  fieldInfo = dataGridView1.GetType().GetField( "  EVENT_DATAGRIDVIEWCELLDOUBLECLICK  " , BindingFlags.Static |  BindingFlags.NonPublic);

                      var  d =  handleList[fieldInfo.GetValue(dataGridView1)];
                      if  (d !=  null  )
                    {
                        d.DynamicInvoke(dataGridView1,   new   DataGridViewCellEventArgs(columnIndex, rowIndex));
                    }
                } 

该方法需要通过反射方式获取EventHandlerList与注册用的key,不过由于Key声明的是private的,所以很难保证MS啥时候就把变量名称改了,总不能每次换版本时都用Reflector查看下把(貌似从.net2.0到4.0该字段名没变过)


办法三
MS控件的事件一般都有一个protected OnXXX签名字样的方法来调用事件处理程序,那么直接反射调用它就完事了,而且由于是protected的比起private要靠谱点.

View Code

 var  dg = dataGridView1.GetType().GetMethod( "  OnCellDoubleClick  " ,BindingFlags.NonPublic |  BindingFlags.Instance);
                dg.Invoke(dataGridView1,  new   object []{  new  DataGridViewCellEventArgs(columnIndex, rowIndex)});



 

 

标签:  事件 ,  Events

 

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于匿名委托注册事件的触发的详细内容...

  阅读:57次