代码之家  ›  专栏  ›  技术社区  ›  Matthias Meid

正在使用-=-运算符注销事件

  •  0
  • Matthias Meid  · 技术社区  · 17 年前

    打开窗口时,我在业务对象上注册了一个“已删除”事件处理程序。它以如下方式传递给构造函数 business :

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

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

    如果用户在当前窗口中删除它,这条消息将是愚蠢的,所以我想在之前注销该事件:

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

    我的问题很简单:无论如何都会显示消息,因此注销不起作用。我尝试将事件处理程序存储在单独的成员中。也不起作用。

    任何帮助都会很酷。

    马蒂亚斯

    P.S.阅读 this post ,恐怕正确注销该事件可能会使其在所有编辑器窗口中都未注册。这可能是下一个问题。 ;-)

    5 回复  |  直到 9 年前
        1
  •  1
  •   TcKs    17 年前

    如果你真的想要这种行为(我不认为,这是一个好的模式,但没关系),你可以从ViewModel类派生,并为删除的作者添加属性。 然后,您可以执行以下操作:

    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;
        }
    }
    
        2
  •  1
  •   Yona    17 年前

    我不知道为什么您的示例代码不能按预期工作,但您可以尝试添加一个私有成员变量,以检查此用户是删除记录还是其他用户。

    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 */
    }
    
        3
  •  1
  •   SwDevMan81    17 年前

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

    business.Deleted -= new EventHandler(business_Deleted);
    查看业务的_invocationCount和_invocationList。已删除(在“基础”->“非公开成员”下),以确保不再注册任何事件。
        4
  •  0
  •   Ed Swangren    17 年前

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

    Business business = (Business)businessBindingSource.DataSource;
    

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

        5
  •  0
  •   Tim Cooper    14 年前

    当然,这是最短的完整示例:

    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();
            }
        }
    }
    

    我想应该是同一个例子,埃德。我说得对吗?

    问候,谢谢你!