簡體   English   中英

事件觸發次數越來越多

[英]Event fires more and more times

我有一個 silverlight mvvm 應用程序加載主視圖,其中 2 個用戶控件加載到 2 個 ContentControls 中,一個帶有顯示項目的列表框,另一個帶有編輯按鈕。 當我單擊編輯按鈕時,2 個新的用戶控件加載到 ContentControls 中,一個顯示要編輯的數據(EditData),另一個顯示保存和取消按鈕(EditAction)。 當我單擊保存按鈕時,它會引發一個在單獨的 GlobalEvents.cs class 中定義的事件,例如:

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

我在另一個用戶控件 EditData 中訂閱了它,因為我需要通過自定義 EventArgs 傳輸編輯過的數據,所以我放入了它的 ViewModel 的構造函數:

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

並在保存數據中:

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

這引發了另一個事件,該事件將先前的用戶控件加載到其 ControlContent 中並在列表框中顯示編輯的數據。 沒關系,但是每當我單擊編輯然后再次保存時,它會引發事件兩次,再次引發 3 次,然后是 4 次,依此類推。 我怎樣才能讓它只被提升一次? 我認為這可能是因為每次單擊編輯時,都會加載用戶控件的新實例,但我不知道,也許對事件的訂閱仍然存在,所以我嘗試粘貼

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

到 Dispose() 方法但沒有成功。 我怎樣才能使這項工作?

當您想從事件中注銷時,您不能使用 lambda。

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

這將創建一個 EventHandler 類型的實例 - 我們稱之為實例 A - 並將其添加為處理程序。

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;
        // ...
    }

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

該行被多次調用,因此您每次都添加一個新的事件處理程序。

您需要將該行移動到僅調用一次的位置,或者將事件處理程序更改為:

this.globalEvents.OnSaveButtonClicked += SaveData;

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

因此,您在處理完事件處理程序后將其刪除。 這假設處理程序將在您下次 go 進入編輯模式時添加回來。

您可以在 class 中定義一個私有事件處理程序委托變量並在您的構造函數中分配它:

private SaveButtonClickedHandler _handler;

在構造函數中分配處理程序:

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

處置:

this.globalEvents.OnSaveButtonClicked -= _handler; 

“SaveButtonClickedHandler”是代表名稱的偽代碼/占位符。

哈薩寧

您必須放入一個適當的事件處理程序方法來調用SaveData()並注冊/取消注冊它。 否則,您嘗試取消注冊另一個“新”匿名方法,而不是您注冊的原始方法,因為它是匿名的,您實際上無法再訪問。

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

this.globalEvents.OnSaveButtonClicked += SaveButtonClicked;

this.globalEvents.OnSaveButtonClicked -= SaveButtonClicked;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM