Отмена регистрации события с оператором - = - - PullRequest
0 голосов
/ 20 ноября 2008

При открытии окна я регистрирую обработчик событий Deleted на моем бизнес-объекте. Он передается конструктору как business:

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

Теперь пользователь может нажать кнопку, чтобы удалить ее (вы знаете, удаляющую запись). Обработчик событий зарегистрирован для захвата удаления другими окнами редактора и уведомления пользователя («Элемент был удален в другом окне редактора».).

Если пользователь удалит его в текущем окне, это сообщение будет глупым, поэтому я хотел бы отменить регистрацию события раньше:

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

Моя проблема проста: сообщение все равно отображается, поэтому отмена регистрации не работает. Я попытался сохранить EventHandler в отдельном члене. Также не работает.

Любая помощь будет крутой.

Matthias

P.S. Читая этот пост , я боюсь, что отмена регистрации события может сделать его незарегистрированным для всех окон редактора. Может быть следующая проблема. ; -)

Ответы [ 5 ]

1 голос
/ 30 июня 2009

Может ли событие быть зарегистрировано более одного раза? Я бы поставил точку останова после

business.Deleted -= new EventHandler(business_Deleted);
и проверил _invocationCount и _invocationList of business.Deleted (в разделе Base -> Непубличные члены), чтобы убедиться, что больше нет зарегистрированных событий.
1 голос
/ 24 ноября 2008

Я не уверен, почему ваш пример кода не работает должным образом, но вы можете попробовать добавить закрытую переменную-член, чтобы проверить, удаляет ли этот пользователь запись или другого пользователя.

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 */
}
1 голос
/ 20 ноября 2008

Если вы действительно хотите такое поведение (я не думаю, что это хороший шаблон, но это не имеет значения), вы можете наследовать класс 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;
    }
}
0 голосов
/ 20 ноября 2008

Конечно, вот кратчайший пример:

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

Я думаю, что это должен быть тот же самый экземпляр, Эд. Я прав с этим?

Привет, и спасибо тебе!

0 голосов
/ 20 ноября 2008

Из нескольких строк, которые я вижу, это может быть проблемой:

Business business = (Business)businessBindingSource.DataSource;

Похоже, вы меняете ссылку на бизнес на другой объект. Возможно, ваш был только примером, и вы каждый раз используете один и тот же объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...