C#取消订阅事件的问题

我的收藏 发布于 2011/07/13 18:24
阅读 2K+
收藏 0
C#

【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告”

在C#2.0之前对象的事件订阅都是

public void Foo(object sender,EventAgrs e){}

obj.OnClick+=new EventHandle(Foo);

取消订阅就是  obj.OnClick-=new EventHandle(Foo);

那么如果是用匿名委托或者 lambda表达式订阅的事件该如何取消订阅?

如 obj.OnClick+=delegate(a,e){};

obj.OnClick+=(a,e)=>{};

像这样的该如何取消订阅?

加载中
1
晓寒
晓寒
一般来说,对于要取消订阅的事件,不要使用匿名代理。
使用匿名委托订阅事件,取消订阅比较麻烦。 
可以这样实现,把委托或匿名方法保存在一个变量中。

订阅及取消时使用这个变量就可以了。


private void TestButton_Click(object sender, RoutedEventArgs e)
{
	MessageBox.Show("Test button click");
}
private RoutedEventHandler reHandler = null;
private void AddEventButton_Click(object sender, RoutedEventArgs e)
{
	reHandler = (s, se) => { TestButton_Click(s, se); };
	//reHandler = delegate(object senderr, RoutedEventArgs ee) { TestButton_Click(senderr, ee); };
	btn1.Click += reHandler;
}

private void RemoveEventButton_Click(object sender, RoutedEventArgs e)
{
	btn1.RemoveHandler(Button.ClickEvent, reHandler);
}
0
我的收藏
我的收藏

引用来自“晓寒”的答案

一般来说,对于要取消订阅的事件,不要使用匿名代理。
使用匿名委托订阅事件,取消订阅比较麻烦。 
可以这样实现,把委托或匿名方法保存在一个变量中。

订阅及取消时使用这个变量就可以了。


private void TestButton_Click(object sender, RoutedEventArgs e)
{
	MessageBox.Show("Test button click");
}
private RoutedEventHandler reHandler = null;
private void AddEventButton_Click(object sender, RoutedEventArgs e)
{
	reHandler = (s, se) => { TestButton_Click(s, se); };
	//reHandler = delegate(object senderr, RoutedEventArgs ee) { TestButton_Click(senderr, ee); };
	btn1.Click += reHandler;
}

private void RemoveEventButton_Click(object sender, RoutedEventArgs e)
{
	btn1.RemoveHandler(Button.ClickEvent, reHandler);
}
谢谢你的回答。可是我想知道那个比较麻烦的取消订阅到底是怎样的呢?
0
晓寒
晓寒

回lz,可以进行这样的尝试,改用反射实现,用反射获得button的eventhandler,并对它进行反注册。

如果有实验结果了的话,别忘记分享下。

我的收藏
我的收藏
楼下有结果了
0
总会有无法选择的时候
总会有无法选择的时候

有难度,想了半天没想到应该怎么做;

不过在微软论坛里找到了一份答案..

private void Form1_Load(object sender, EventArgs e)
{
    this.button1.Click += delegate(object a, EventArgs b)
    {
        MessageBox.Show("Test!");
    };
}
private void button2_Click(object sender, EventArgs e)
{
    Type t = button1.GetType();
    PropertyInfo pi = t.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
    EventHandlerList ehl = (EventHandlerList)pi.GetValue(button1, null);
    FieldInfo fieldInfo = (typeof(Control)).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);
    Delegate d = ehl[fieldInfo.GetValue(null)];
    if (d != null)
    {
        foreach (Delegate temp in d.GetInvocationList())
        {
            ehl.RemoveHandler(fieldInfo.GetValue(null), temp);
        }
    }
}
原文: http://social.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/9211ba35-001f-4319-a8e6-96e53995fbf9
我的收藏
我的收藏
谢谢
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部