Событие происходит все больше и больше - PullRequest
7 голосов
/ 01 июня 2011

У меня есть приложение silverlight mvvm, которое загружает основной вид с 2-мя пользовательскими элементами управления, загруженными в 2 ContentControls, один со списком, отображающим элементы, а другой с кнопкой редактирования.Когда я нажимаю кнопку «Изменить», в ContentControls загружаются 2 новых пользовательских элемента управления, один из которых показывает данные для редактирования (EditData), а другой - кнопку «Сохранить и отменить» (EditAction).Когда я нажимаю кнопку «Сохранить», возникает событие, определенное в отдельном классе GlobalEvents.cs, например:

public event EventHandler OnSaveButtonClicked;  
public void RaiseSaveButtonClicked()  
{  
  this.OnSaveButtonClicked(this, EventArgs.Empty);  
}

, и я подписываюсь на него в другом пользовательском элементе управления EditData, потому что мне нужно передать эти отредактированные данные.через пользовательские EventArgs, поэтому я поместил в конструктор его ViewModel:

this.globalEvents.OnSaveButtonClicked += (s, e) => SaveData();  

и в Save data:

public void SaveData()  
{  
    globalEvents.RaiseSaveData(EditedGuy);     
}  

, который вызывает другое событие, которое загружает предыдущие пользовательские элементы управления в ихControlContent и показывает отредактированные данные в списке.Это все хорошо, но всякий раз, когда я нажимаю на правку и затем снова сохраняю, это вызывает событие дважды, и снова 3 раза, затем 4 и так далее.Как я могу сделать это, чтобы быть поднятым только один раз?Я подумал, что это может быть потому, что каждый раз, когда я нажимаю кнопку «Изменить», загружается новый экземпляр пользовательского элемента управления, и я не знаю, может быть, подписка на событие остается, поэтому я попытался вставить

this.globalEvents.OnSaveButtonClicked -= (s, e) => SaveData(); 

вметод Dispose (), но безуспешно.Как я могу сделать эту работу?

Ответы [ 4 ]

7 голосов
/ 01 июня 2011

Вы не можете использовать лямбды, если хотите отменить регистрацию в событиях.

this.globalEvents.OnSaveButtonClicked += (s, e) => SaveData(); 

Это создаст один экземпляр - назовем его экземпляром A - типа EventHandler и добавим его в качестве обработчика.*

this.globalEvents.OnSaveButtonClicked -= (s, e) => SaveData(); 

Это не удалит экземпляр A из события, но создаст новый экземпляр - экземпляр B - и попытается удалить его из события.

Чтобы устранить эту проблему, либо создайте небольшой методили сохраните этот анонимный метод в поле:

class ViewModel
{

    private EventHandler _saveButtonClickedHandler;
    // ...

    public ViewModel()
    {
        _saveButtonClickedHandler = (s, e) => SaveData();
        this.globalEvents.OnSaveButtonClicked += _saveButtonClickedHandler;
        // ...
    }

    public void Dispose()
    {
        this.globalEvents.OnSaveButtonClicked -= _saveButtonClickedHandler;
        // ...
    }

    // ...
}
2 голосов
/ 01 июня 2011

Вы можете определить личную переменную-делегат обработчика событий в своем классе и назначить ее в своем конструкторе:

private SaveButtonClickedHandler _handler;

Назначить обработчик в своем конструкторе:

_handler = (s,e) => SaveData();
this.globalEvents.OnSaveButtonClicked += _handler;

Утилизация:

this.globalEvents.OnSaveButtonClicked -= _handler; 

«SaveButtonClickedHandler» является псевдокодом / заполнителем для любого имени делегата.

Hasanain

2 голосов
/ 01 июня 2011
this.globalEvents.OnSaveButtonClicked += (s, e) => SaveData();

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

Вам нужно либо переместить эту строку туда, где она вызывается только один раз, либо изменить обработчик события на:

this.globalEvents.OnSaveButtonClicked += SaveData;

public void SaveData(object sender, EventArgs e)  
{  
    globalEvents.RaiseSaveData(EditedGuy);     
    this.globalEvents.OnSaveButtonClicked -= SaveData();
}

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

0 голосов
/ 01 июня 2011

Вам нужно будет ввести правильный метод обработчика событий, который вызывает SaveData(), и зарегистрировать / отменить его регистрацию. В противном случае вы попытаетесь отменить регистрацию другого «нового» анонимного метода вместо исходного, который вы зарегистрировали, к которому вы, поскольку он анонимный, больше не можете получить доступ.

public void SaveButtonClicked(object sender, EventArgs e)
{
    SaveData();
}

this.globalEvents.OnSaveButtonClicked += SaveButtonClicked;

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