我有一个可以发布事件的objectRaiser,例如事件“PropertyChanged”。 我还有另一个objectListener,它从第一个objectRaiser监听引发的事件。
如何从objectRaiser实例中删除objectListener侦听的事件处理程序?
我需要重复一些重要的事情:remove的事件处理程序来自objectListener。不适合我删除objectRaiser的所有出版物。我在另一个问题中看到了这个但似乎不能解决我的问题。
关心并多多感谢您的帮助。
答案 0 :(得分:0)
从objectRaiser
内部:
MyEvent = null;
从外部:您不能,因为您无权访问存储处理程序的委托。但是,您可以在ClearHandlers()
中添加公开objectRaiser
方法,并在任意位置调用。
答案 1 :(得分:0)
我不确定这是否正是您所追求的...但在下面的代码中,我们可以使用Reflection
从包含在ObjectRaiser
的实例中删除处理程序ObjectListener
:
namespace ObjectEvents
{
class Program
{
private class ObjectRaiser
{
public event EventHandler PropertyChange;
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
PropertyChange(this, new EventArgs());
}
}
}
private class ObjectListener
{
private ObjectRaiser or;
public ObjectListener(ObjectRaiser or)
{
this.or = or;
or.PropertyChange += new EventHandler(PropertyChange);
}
public void PropertyChange(object sender, EventArgs e)
{
Console.WriteLine("I'm listening!");
}
public void RemoveHandlers()
{
var lfi = or.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach(var fi in lfi)
{
var eh = fi.GetValue(or) as EventHandler;
if (eh != null)
{
foreach (var del in eh.GetInvocationList())
{
foreach (var ev in or.GetType().GetEvents())
{
ev.GetRemoveMethod().Invoke(or, new object[] { del });
}
}
}
}
}
}
static void Main(string[] args)
{
var or = new ObjectRaiser();
var ol = new ObjectListener(or);
//This will raise the event
or.Name = "New Name";
ol.RemoveHandlers();
//This will throw an exception because the event has no handler associated
or.Name = "Weird Name";
Console.ReadLine();
}
}
}
注意:这是一个非常简单的示例,肯定需要对实际使用进行重大修改。