È un ViewModel "God" desiderato in WPF

5

La mia applicazione ha controlli utente all'interno dei controlli utente. Si prega di vedere una schermata di una delle più belle applicazioni di tutti i tempi (UC = controllo utente):

TutteleproprietàvivononelcodiceMainWindowdietro,noncenesononeimieiUserControls.Perlegareallemieproprietà,iouso

DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=Window}}"

Funziona bene, ma significa che tutte le proprietà di binding sono nel mio codice MainWindow dietro (o MainWindow ViewModel).

Questo è voluto in un approccio MVVM (o dovrei dire WPF), in quanto tutti i bambini condividono lo stesso ViewModel?

    
posta Dave 06.12.2013 - 10:03
fonte

2 risposte

6

Penso che la sua cattiva pratica di avere un God ViewModel, il ViewModel più in alto, chiamiamolo MainWindowViewModel , dovrebbe contenere solo dati e comportamenti accoppiati a quelli della MainWindow, che di solito è molto sottile, tutti gli altri lavori dovrebbero essere delegati a submodels.

Se hai un gestore di docking o un'altra logica di gestore di finestre, il codice dovrebbe risiedere in MainWindowViewModel .

Ecco un esempio di un ViewModel che ho creato che delega il comportamento ai sotto-modelli

link

Non penso che sia una buona pratica passare i dati ai sotto-modelli, crea dipendenze tra i modelli. È preferibile utilizzare un modello di aggregazione degli eventi, in questo modo tutti i modelli interessati alla modifica dei dati possono iscriversi all'evento.

Aggiornamento : ho apportato un miglioramento al mio modello di finestra principale, invece del costruttore che ha preso tutti i modelli di vista secondaria ora prende una collezione di modelli viewmodels. E poi configuro IoC per iniettare modelli corretti

private void ConfigurePanels()
{
    kernel.Bind<PanelViewModel>().To<ConsoleViewModel>();
    kernel.Bind<PanelViewModel>().To<ErrorsViewModel>();
    kernel.Bind<PanelViewModel>().To<WatchesViewModel>();
}

Questo rende il modello principale un po 'meno accoppiato ai sub-modelli, prima di cambiare

    public MainShellViewModel(ConsoleViewModel consoleViewModel,
                              ErrorsViewModel errorsViewModel,
                              WatchesViewModel watchesViewModel
        )
        : base(resultFactory)
    {            
        Tools = new BindableCollection<PanelViewModel> {consoleViewModel, errorsViewModel, watchesViewModel};
    }

e dopo

    public MainShellViewModel(IEnumerable<PanelViewModel> panels)
        : base(resultFactory)
    {
        Tools = new BindableCollection<PanelViewModel> (panels);
    }

link

    
risposta data 13.01.2014 - 14:13
fonte
1

Salvo sovrascrittura, i controlli figlio erediteranno DataContext (tranne che per i figli di un oggetto ItemsControl).

Se non imposti esplicitamente il DataContext su tutti i tuoi controlli dovresti stare bene (ma il tuo accoppiamento è alto ... cioè, il tuo usercontrol ora presume che sarà usato solo in una configurazione specifica)

Se si imposta in modo esplicito DataContext, questo diventa un problema di Dipendenza iniezione. Se un comando grand-grandchild usercontrols richiede i dati dal viewmodel più in alto, allora quei dati dovrebbero probabilmente essere passati al viewmodel di livello più vicino. Pensaci. Questi dati sono chiaramente una dipendenza del ViewModel associato a UserControl.

    
risposta data 06.12.2013 - 12:10
fonte

Leggi altre domande sui tag