C# 使用代码删除事件处理程序

C# 使用代码删除事件处理程序,c#,reflection,event-handling,C#,Reflection,Event Handling,可以使用按钮单击事件中的以下代码删除事件处理程序 按钮btn=新按钮(); this.Controls.Add(btn); 点击+=(o,x)=> { 按钮b=o作为按钮; FieldInfo eventclick=typeof(Control).GetField(“eventclick”,BindingFlags.Static | BindingFlags.NonPublic); 对象eventValue=eventclick.GetValue(b); PropertyInfo events=

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

按钮btn=新按钮();
this.Controls.Add(btn);
点击+=(o,x)=>
{
按钮b=o作为按钮;
FieldInfo eventclick=typeof(Control).GetField(“eventclick”,BindingFlags.Static | BindingFlags.NonPublic);
对象eventValue=eventclick.GetValue(b);
PropertyInfo events=b.GetType().GetProperty(“事件”,BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList EventHandlerList=(EventHandlerList)events.GetValue(b,null);
RemoveHandler(eventValue,eventHandlerList[eventValue]);
MessageBox.Show(“测试”);
};
但是我想从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))

在SO中需要归属。没有链接你找到的答案实际上会阻止你得到一个好的答案。