0

当打开一个窗口时,我在我的业务对象上注册了一个 Deleted-event-handler。它被传递给构造函数business

business.Deleted += new EventHandler<EventArgs>(business_Deleted);

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

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

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

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

任何帮助都会很酷。

马蒂亚斯

PS阅读这篇文章,我担心正确取消注册事件可能会使它在所有编辑器窗口中取消注册。可能是下一个问题。;-)

4

5 回答 5

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;
    }
}
于 2008-11-20T08:51:16.830 回答
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 */
}
于 2008-11-24T18:43:45.760 回答
1

活动可以注册多次吗?我会在之后放一个断点

business.Deleted -= new EventHandler(business_Deleted);
并检查 business.Deleted 的 _invocationCount 和 _invocationList (在 Base -> Non-Public members 下)以确保没有更多事件注册。

于 2009-06-30T04:05:19.727 回答
0

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

Business business = (Business)businessBindingSource.DataSource;

看起来您正在将业务持有的引用更改为不同的对象。也许您的只是一个示例,并且您每次都使用相同的对象。

于 2008-11-20T08:13:26.690 回答
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。我说得对吗?

问候,并感谢你!

于 2008-11-20T08:31:35.217 回答