2009-04-28 12 views
20

Nella mia applicazione WPF ho 2 di Windows (sia per Windows hanno un proprio ViewModel):WPF MVVM modo corretto per generare l'evento in mostra dal ViewModel

  1. finestra principale di applicazione che visualizza la lista con il mazzo di parole (rilegato a MainViewModel)

  2. finestra di dialogo che permette agli utenti di aggiungere nuove voci alla lista (legato a AddWordViewModel)

MainViewModel ha articoli proprietà di Li st (questa raccolta è popolata da una delle classi di servizio) associata a ListBox della finestra principale

AddWordViewModel dispone di SaveWordCommand associato al pulsante Salva finestra di dialogo di Word. Il suo compito è prendere il testo inserito dall'utente e passarlo alla classe di servizio.

Dopo che l'utente fa clic sul pulsante Salva, è necessario informare MainViewModel per ricaricare gli articoli dal servizio.

la mia idea era di esporre il comando pubblica in MainViewModel ed eseguirlo da AddWordViewModel

Qual è il modo corretto per la sua attuazione?

Grazie!

risposta

18

Event Aggregators sono un bel modo per risolvere questo tipo di problema. Fondamentalmente c'è una classe centralizzata (per amor di semplicità diciamo che è un Singleton e affrontare la possibile ira dei ragazzi anti-singleton) che è responsabile del trasferimento di eventi da un oggetto all'altro. Con i vostri nomi di classe l'utilizzo può apparire come:

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>(); 
     event.Subscribe(WordAdded); 
    } 

    protected virtual void WordAdded(object sender WordAddedEventArgs e) 
    { 
     // handle event 
    } 
} 

public class AddWordViewModel 
{  
    //From the command 
    public void ExecuteAddWord(string word) 
    { 
     WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>(); 
     event.Publish(this, new WordAddedEventArgs(word)); 
    } 
} 

Il vantaggio di questo modello è che si può facilmente estendere l'applicazione per avere più modi di parole che creano e molteplici ViewModels che sono interessati a parole che sono state aggiunte e non vi è alcun accoppiamento tra i due in modo da poterli aggiungere e rimuovere come necessario.


Se si vuole evitare il Singleton (e per scopi di test Vorrei suggerire di fare) allora può valere la pena guardare in iniezione di dipendenza, anche se questo è davvero tutto un altro problema.


Ok, pensiero finale. Vedo dalla rilettura della tua domanda che hai già una sorta di classe di servizio di Word che gestisce il recupero e l'archiviazione degli oggetti di Word. Non c'è motivo per cui il servizio non possa essere responsabile dell'innalzamento dell'evento quando viene aggiunta la nuova parola poiché entrambi i ViewModel sono già accoppiati ad esso. Anche se mi piacerebbe ancora suggerire l'EventAggregator è più flessibile e una soluzione migliore, ma YAGNI possono applicare qui

public class WordService 
{ 
    public event EventHandler<WordAddedEventArgs> WordAdded; 

    public List<string> GetAllWords() 
    { 
     //return words 
    } 

    public void SaveWord(string word) 
    { 
     //Save word 
     if (WordAdded != null) WordAdded(this, new WordAddedEventArgs(word)); 
     //Note that this way you lose the reference to where the word really came from 
     //probably doesn't matter, but might 
    } 
} 

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     //Add eventhandler to the services WordAdded event 
    } 
} 

Che cosa si vuole evitare di fare anche se sta introducendo l'accoppiamento tra ViewModels che si creerà chiamando un comando su un ViewModel con l'altro, questo limiterà severamente le opzioni per espandere l'applicazione (e se un secondo ViewModel fosse interessato a nuove parole, è ora anche l'AddWordViewModel a dirlo?)

+0

Grazie per la descrizione molto dettagliata risposta. Dovrò scavare dentro :) Un sacco di divertimento in arrivo :) –

+0

Sono andato al massimo OO con un enorme oggetto grafico per la mia implementazione MVVM.2 anni su tutta la linea e fare cambiamenti strutturali è piuttosto difficile. Vorrei essere andato per il modello aggregatore/mediatore in quanto la flessibilità è enorme. ATTENZIONE: perdite di memoria. Assicurati che il tuo aggregatore utilizzi riferimenti deboli. – Gusdor

Problemi correlati