zoukankan      html  css  js  c++  java
  • 匿名委托注册事件的触发

    需求
    需要在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

     

  • 相关阅读:
    Shell从入门到精通进阶之四:流程控制
    15个Python面试问题(附答案)
    python教程:内置函数和语法糖触发魔法方法
    python教程:利用while求100内的整数和
    python 教程:read(),readline() 和 readlines() 比较
    python生成随机数:uniform(), randint(), gauss(), expovariate()
    Python教程: 字符串转义序列及格式化
    python单例模式的五种实现方式
    Python NumPy的常用函数
    python五种调试或排错的方法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2670108.html
Copyright © 2011-2022 走看看