匿名委托注册事件的触发
需求
需要在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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did48116