2011-06-01 11 views
7

2 ContentControls'e yüklenen 2 kullanıcı denetimi ile ana görünümü yükleyen bir gümüş ışığı mvvm uygulamasına sahibim. Düzenleme düğmesini tıklattığımda, 2 yeni kullanıcı denetimi ContentControls'e yüklenir; biri düzenlenmesi gereken verileri (EditData) ve diğer Kaydet ve İptal düğmesini (EditAction) gösterir. i düğmesine kaydetmek tıkladığınızda , bu gibi ayrı GlobalEvents.cs sınıfında tanımlanan bir olay yükseltir:Olay her gün daha fazla yanıyor

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

ve ben aracılığıyla o düzenlenmiş veri aktarmak gerekir çünkü ben, diğer kullanıcı kontrolünde EditData kendisine abone

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

ve kaydet verilerinde

:

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

başka eve yükseltir özel EventArgs, bu yüzden bunun yapıcısı koyduk ViewModel var Önceki kullanıcı kontrollerini ControlContent'e yükler ve düzenlenmiş verileri liste kutusunda gösterir. Thats tüm iyi, ama ben düzenlemek ve daha sonra yeniden kaydetmek, her zaman olay iki kez ve tekrar 3 kez, sonra 4 ve daha sonra yükseltir. Bunu sadece bir kez yükseltmek için nasıl yapabilirim? Ben her zaman ben düzenle seçeneğini tıklayın, çünkü kullanıcı denetimi yeni bir örneği yüklenir ve belki olaya abonelik kalır i dont know, bu yüzden Dispose için

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

yapıştırmak için çalıştık olabileceğini düşündüm() yöntemi başarılı olmaksızın. Bu işi nasıl yapabilirim?

cevap

7

Olaylardan kaydını silmek istediğinizde lambdaları kullanamazsınız.

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

Bu bir örneğini oluşturur - tipi EventHandler ve bir işleyici olarak ekleyin - en örneği A diyelim.

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

Bu

olaydan örnek kaldırılacak ancak yeni bir örneğini oluşturmaz - örneği B - ve olay çıkarmak için çalışır. Yeni bir olay işleyicisi her zaman ekliyoruz böylece birden çok kez bu hat çağrıldığını

class ViewModel 
{ 

    private EventHandler _saveButtonClickedHandler; 
    // ... 

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

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

    // ... 
} 
+0

Çok teşekkürler! Lambdas'ın olaylardan kurtulmak için kullanılamayacağını bilmiyordum. Kötü, bana doğru yolu gösterdiğin için teşekkürler:] –

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

:

Bu sorunu çözmek, ya biraz yöntemi oluşturun veya bir tarlada isimsiz yöntemi kaydetmek için . Yani bu cihazla uğraştıktan sonra olay işleyicisi kaldırmak

this.globalEvents.OnSaveButtonClicked += SaveData; 

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

:

Bunu yalnızca bir kez denir bir yere o çizgiyi taşımak veya olay işleyicisi değiştirmek gerek duyarsınız. Bu, düzenleme moduna geçtiğinizde işleyicinin tekrar ekleneceğini varsayar.

+0

Teşekkür ederim, bu tam olarak aradığım şeydi. –

+0

Bir şey daha, sadece kendim için net bir şey yapmak için, etkinlik çağrısını yapıcı yerine farklı bir yöntemle yerleştirmeyi denedim, ancak bu satırdaki GlobalEvents sınıfında this.OnSaveButtonClicked (bu, EventArgs.Empty); Boş olan istek istisnasını alıyorum. Niye ya? –

0

SaveData()'u çağıran uygun bir olay işleyicisi yöntemini girmeniz ve kaydetmeniz/kaydetmeniz gerekir. Aksi halde, kaydettiğiniz orijinal yerine başka bir "yeni" anonim yöntem kaydını silmeye çalışırsınız; bu, anonim olduğu için artık erişemezsiniz.

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

this.globalEvents.OnSaveButtonClicked += SaveButtonClicked; 

this.globalEvents.OnSaveButtonClicked -= SaveButtonClicked; 
2

Sınıfının özel eventhandler temsilci değişken tanımlamak ve yapıcı bunu atayabilirsiniz:

private SaveButtonClickedHandler _handler; 

Yapıcınızda içinde işleyicisi atama:

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

bertaraf:

this.globalEvents.OnSaveButtonClicked -= _handler; 

"SaveButtonClickedHandler", temsilci adı ne olursa olsun sözde kod/yer tutucudur.

Hasanain

+0

Bu tam cevap yaklaşık 10 dakika önce verildi ... –

+0

Doğru, bu yazmaya başladığımda cevabını görmedim ... – Hasanain