![](/img/trans.png)
[英]OnCheckedChanged event fires more and more times for every time it is clicked
[英]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.