MVVM Luce Toolkit - RelayCommands, DelegateCommands, e ObservableObjects
-
15-10-2019 - |
Domanda
Ho appena iniziato a sperimentare con Laurent Bugnion MVVM Luce Toolkit . Penso che ho intenzione di piace molto, ma ho un paio di domande.
Prima di arrivare a loro, mi permetta di spiegare dove sto venendo. Attualmente uso una combinazione di MVVM Fondazione di Josh Smith e un altro progetto su CodePlex chiamato MVVM Toolkit . Io uso ObservableObject
e Messenger
da MVVM Fondazione e DelegateCommand
e CommandReference
da MVVM Toolkit.
L'unica vera sovrapposizione tra MVVM Fondazione e MVVM Tookit è che entrambi hanno un'implementazione per ICommand
: MVVM Fondazione ha RelayCommand
e MVVM Tookit ha DelegateCommand
. Di questi due, DelegateCommand
sembra essere più sofisticati. Si avvale di un CommandManagerHelper
che utilizza riferimenti deboli a perdite di memoria evitare.
Detto questo, qui sono le mie domande:
-
Perché MVVM Luce uso
RelayCommand
piuttosto cheDelegateCommand
? È l'uso di riferimenti deboli in unICommand
inutili o non è raccomandato per qualche motivo? -
Perché non c'è
ObservableObject
in MVVM Luce?ObservableObject
è fondamentalmente solo la parte diViewModelBase
che implementaINotifyPropertyChanged
, ma è molto conveniente avere come classe separata perché view-modelli non sono gli oggetti solo necessità di attuareINotifyPropertyChanged
. Per esempio, diciamo che si dispone di un DataGrid che si lega a un elenco di oggettiPerson
. Se una delle proprietà aPerson
può cambiare mentre l'utente sta visualizzando il DataGrid,Person
avrebbe bisogno di implementareINotifyPropertyChanged
. (Mi rendo conto che sePerson
viene generato automaticamente usando qualcosa come LinqToSql, probabilmente già implementareINotifyPropertyChanged
, ma ci sono casi in cui ho bisogno di fare le versioni Vista-specifici di oggetti del modello entità, diciamo, perché ho bisogno di includere un comando per sostenere una colonna pulsante in un DataGrid.)
Grazie.
P.S. Ecco il codice per DelegateCommand
dal MVVM Toolkit:
https://docs.google.com/document/pub?id=1ApCx5SbCfHi5fBhv8Ki3zA6j34sp2t80LQZdj89v8cU
Soluzione
Sembra che il problema sollevato dalla prima questione è stata risolta nella ultima build:
Il MVVM Luce Toolkit Codeplex sito (sotto "Alzare l'evento CanExecuteChanged manualmente"), il CommandManager
è stata eliminata del tutto.
Per quanto riguarda Observable Object
, ho aggiunto un elemento alla issue tracker sul Codeplex sito.
Altri suggerimenti
Si può anche prendere in considerazione Catel . Supporta una DataObject (sia generici e non generici) che il sostegno esattamente quello che stai cercando (un oggetto che implementa INotifyPropertyChanged, IDataErrorInfo, e molto altro). Poi, il ViewModelBase è derivata dalla classe molto potente DataObjectBase, in modo da poter utilizzare il DataObjectBase per oggetti di dati, e la ViewModelBase per i modelli di visualizzazione.
E 'consente di risparmiare anche dalla creazione di messaggeri perché si può semplicemente utilizzare l'attributo interestedin su un modello al fine di ricevere le notifiche di modifica di un altro modello di vista.
Entrambe le vostre domande suggeriscono fortemente a me che si preferisce utilizzare qualcosa di più che il concetto Visualizza modello per definire la logica di business.
Il DelegateCommand
definisce un separato di classe a parte il Model View. Il ObservableObject
è un'istanza di un separato di classe a parte il Model View. Questa non è una regola, ma preferenza personale del momento: la vista del modello è sufficiente per me come un contenitore per la logica di business, in materia di effetti visivi. Questo può tradire la mia preferenza per MVVM Luce --- che non trovo manca in questo momento.
Non sono del tutto certo di quello che sta succedendo nel esempio DataGrid. Quello che posso dire è che il DataGrid non è molto flessibile --- tuttavia, in WPF, il DataGridTemplateColumn
può dichiarativo legano una vista del modello per una visualizzazione (controllo ad esempio un utente). Quindi, forse questo ha un senso:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataView="{x:Type m:YourViewModelForButton}">
<v:YourViewWithButton/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>