使用 - = - 运算符取消注册事件

时间:2008-11-20 08:05:26

标签: c# winforms events event-handling

打开窗口时,我在业务对象上注册了Deleted-event-handler。它以business

的形式传递给构造函数
business.Deleted += new EventHandler<EventArgs>(business_Deleted);

现在,用户可以单击按钮将其删除(删除记录,您知道)。注册事件处理程序以捕获其他编辑器窗口的删除并通知用户(“项目已在另一个编辑器窗口中删除。”)。

如果用户在当前窗口中删除它,则此消息将是愚蠢的,因此我想在以下情况下取消注册该事件:

Business business = (Business)businessBindingSource.DataSource;
business.Deleted -= new EventHandler<EventArgs>(business_Deleted);

我的问题很简单:无论如何都会显示该消息,因此取消注册不起作用。我尝试将EventHandler存储在一个单独的成员中。也不起作用。

任何帮助都会很酷。

的Matthias

P.S。阅读this post,我担心正确取消注册该事件可能会使所有编辑窗口都未注册。可能是下一个问题。 ; - )

5 个答案:

答案 0 :(得分:1)

如果你真的想要这种行为(我不认为,这是好的模式,萌芽无关紧要),你可以从EventArgs类派生并为删除作者添加属性。 然后你可以这样做:

c.Delete( this ); //this = window
// ...
void business_Deleted(object sender, EventArgs e) {
    bool isDeletedFromMe = false;
    if ( e is DeletedEventArgs ) { isDeletedFromMe = object.ReferenceEquals( this, e.Author ); }
    if ( false == isDeletedFromMe ) {
        MessageBox.Show("Item has been deleted in another editor window.",
            "...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        Close();
    }
}

或者你可以这样做:

void business_Deleted(object sender, EventArgs e)
{
    if ( false == object.ReferenceEquals( sender, this.currentlyDeletingBusiness ) ) {
        MessageBox.Show("Item has been deleted in another editor window.",
            "...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    }
    Close();
}

Business currentlyDeletingBusiness;
private void deleteButton_Activate(object sender, EventArgs e)
{
    Business c = (Business)businessBindingSource.DataSource;
    try {
        this.currentlyDeletingBusiness = c;
        c.Delete();
    }
    finally {
        this.currentlyDeletingBusiness = null;
    }
}

答案 1 :(得分:1)

我不确定为什么您的示例代码无法按预期工作,但您可以尝试添加私有成员变量来检查此用户是否正在删除记录或其他用户。

private bool otherUser = true;

void business_Deleted(object sender, EventArgs e)
{
    if(otherUser) {
        /* Show message */
    }
}

void deleteButton_Activate(object sender, EventArgs e)
{
    otherUser = false;
    /* Delete record */
}

答案 2 :(得分:1)

活动可以多次注册吗?我会在

business.Deleted -= new EventHandler(business_Deleted);
之后设置一个断点并检查business.Deleted的_invocationCount和_invocationList(在Base - &gt; Non-Public成员下),以确保没有更多的事件被注册。

答案 3 :(得分:0)

从我看到的几行,这可能是问题:

Business business = (Business)businessBindingSource.DataSource;

看起来您正在将业务持有的引用更改为其他对象。也许你的只是一个例子而且你每次都使用相同的对象。

答案 4 :(得分:0)

当然,这是最短的完整样本:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication
{
    public partial class BusinessEditor : Form
    {
        private EventHandler<EventArgs> businessDeletedHandler;

        public BusinessEditor(Business business)
            : this()
        {
            InitializeComponent();

            businessBindingSource.DataSource = business;

            // Registering
            businessDeletedHandler = new EventHandler<EventArgs>(business_Deleted);
            business.Deleted += businessDeletedHandler;
        }

        void business_Deleted(object sender, EventArgs e)
        {
            MessageBox.Show("Item has been deleted in another editor window.",
                "...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            Close();
        }

        private void deleteButton_Activate(object sender, EventArgs e)
        {
            Business c = (Business)businessBindingSource.DataSource;
            // Unregistering
            c.Deleted -= businessDeletedHandler;
            c.Delete();
            Close();
        }
    }
}

我认为它应该是同一个实例,Ed。我是对的吗?

迎接,谢谢你!