用代码删除事件处理程序

本文关键字:程序 事件处理 码删除 代码 | 更新日期: 2023-09-27 18:05:23

可以使用以下代码在按钮单击事件中删除事件处理程序。

Button btn = new Button();
this.Controls.Add(btn);
btn.Click += (o, x) =>
{
    Button b = o as Button;
    FieldInfo eventclick = typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);
    object eventValue = eventclick.GetValue(b);
    PropertyInfo events = b.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
    EventHandlerList eventHandlerList = (EventHandlerList)events.GetValue(b, null);
    eventHandlerList .RemoveHandler(eventValue, eventHandlerList [eventValue]);
    MessageBox.Show("Test");
};

但是我想从vgridcontrols CellValueChanged事件中删除事件处理程序。我需要为下面的"EventClick"写些什么?

FieldInfo eventclick = typeof(Control).GetField(
    "EventClick",
    BindingFlags.Static | BindingFlags.NonPublic);

用代码删除事件处理程序

你不能可靠地从事件中删除一个事件处理程序,除非你已经有一个可以用正常方式与-=使用的"equal"委托。

获取带有反射的字段并对其进行修改显然违反了封装,使您的代码极其脆弱。我强烈建议不要这样做。

我不清楚你所说的"vgridcontrols"(DataGridView ?)是什么意思,但无论你想出什么解决方案,都必须是特定于实现的——而且这种实现很容易随着下一个版本的变化而改变。

相反,应该花时间想出一种设计,要么根本不需要删除事件处理程序,要么保留对该处理程序的引用,并可以以正常方式删除它。

这是VB。NET,但您可以轻松地将其修改为c#。这就是你想要的:

'Remove the handler from the cell value changed
Dim gv As DataGridView = Me.equipmentGridView
Dim fInf As FieldInfo = GetType(DataGridView).GetField("EVENT_DATAGRIDVIEWCELLVALUECHANGED", BindingFlags.Static Or BindingFlags.NonPublic)
Dim del As Object = fInf.GetValue(gv)
Dim pInf As PropertyInfo = gv.GetType().GetProperty("Events", BindingFlags.NonPublic Or BindingFlags.Instance)
Dim evList As EventHandlerList = pInf.GetValue(gv, Nothing)
evList.RemoveHandler(del, evList(del))