事件发生的次数越来越多

dec*_*ain 7 c# silverlight events event-handling mvvm

我有一个silverlight mvvm应用程序加载主视图,其中2个用户控件加载到2个ContentControls中,一个用listbox显示项目,另一个用edit编辑按钮.当我单击编辑按钮时,2个新用户控件加载到ContentControls中,一个显示要编辑的数据(EditData),另一个显示保存和取消按钮(EditAction).当我单击"保存"按钮时,它会引发一个在单独的GlobalEvents.cs类中定义的事件,如:

public event EventHandler OnSaveButtonClicked;  
public void RaiseSaveButtonClicked()  
{  
  this.OnSaveButtonClicked(this, EventArgs.Empty);  
}
Run Code Online (Sandbox Code Playgroud)

并且我在其他用户控件EditData中订阅它,因为我需要通过自定义EventArgs传输该编辑数据,所以我已经放入了它的ViewModel的构造函数:

this.globalEvents.OnSaveButtonClicked += (s, e) => SaveData();  
Run Code Online (Sandbox Code Playgroud)

并在保存数据中:

public void SaveData()  
{  
    globalEvents.RaiseSaveData(EditedGuy);     
}  
Run Code Online (Sandbox Code Playgroud)

这会引发另一个事件,将以前的用户控件加载到其ControlContent中,并在列表框中显示已编辑的数据.多数民众赞成,但每当我点击编辑然后再次保存时,它会将事件提升两次,然后再提高3次,然后再提高4次,依此类推.我怎样才能让它只被提升一次?我认为这可能是因为每次我点击编辑,加载了一个新的用户控件实例,我不知道,也许订阅该事件,所以我试图粘贴

this.globalEvents.OnSaveButtonClicked -= (s, e) => SaveData(); 
Run Code Online (Sandbox Code Playgroud)

到Dispose()方法但没有成功.我怎样才能做到这一点?

Dan*_*rth 7

如果要从事件中取消注册,则无法使用lambdas.

this.globalEvents.OnSaveButtonClicked += (s, e) => SaveData(); 
Run Code Online (Sandbox Code Playgroud)

这将创建一个实例 - 让我们称之为实例A - 类型为EventHandler并将其添加为处理程序.

this.globalEvents.OnSaveButtonClicked -= (s, e) => SaveData(); 
Run Code Online (Sandbox Code Playgroud)

这不会从事件中删除实例A,而是创建一个新实例 - 实例B - 并尝试将其从事件中删除.

要解决此问题,请创建一个小方法或在字段中保存该匿名方法:

class ViewModel
{

    private EventHandler _saveButtonClickedHandler;
    // ...

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

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)