Stato degli articoli selezionati in view o viewmodel?

0

Io e il mio collega stavamo discutendo su MVVM e su come gli elenchi e gli elementi selezionati dovrebbero essere archiviati in view / viewmodel.

Penso che il viewmodel dovrebbe solo offrire i dati e consentire alla vista di interpretarlo come gli piace. Potrebbe mostrarlo come una lista con un oggetto selezionato o potrebbe mostrarlo in modo completamente diverso.

Quindi penso che il viewmodel dovrebbe apparire così:

public class MajorVM
{
    ObservableCollection<MinorVM> List
}

E la vista come questa:

<Grid>
    <Listbox Key=ListBox Items=Binding DataContext.List />
    <ContentControl Content=Binding ListBox.SelectedItem />
</Grid>

Il mio collega pensa che sto cambiando tra i contesti dei dati rendendo il codice di visualizzazione più difficile da seguire.

Il mio collega ritiene che il viewmodel dovrebbe contenere lo stato della vista e che ciò consentirà una più facile manipolazione della vista in futuro. Per esempio. controllare la selezione tramite il viewmodel.

Quindi sembrerebbe:

public class MajorVM
{
    ObservableCollection<MinorVM> List
    MinorVM SelectedItem
}

Con una vista simile a questa:

<Grid>
    <Listbox Items=Binding DataContext.List />
    <ContentControl Content=Binding DataContext.SelectedItem />
</Grid>

Per me questo non sembra corretto perché viewmodel ora ha una proprietà SelectedItem su di essa che non è menzionata in nessun'altra parte oltre alla vista. Si tratta di un'implementazione di visualizzazione su viewmodel.

    
posta user3161729 06.08.2018 - 16:04
fonte

3 risposte

3

È generalmente meglio associare i controlli nella vista alle proprietà del ViewModel piuttosto che in altri aspetti della vista.

C'è un chiaro vantaggio per ViewModel che ha SelectedItem in questo caso, ovvero senza esso nessun oggetto viene inizialmente selezionato quando viene visualizzata la vista.

È difficile mettere una linea nella sabbia che demark 'questa funzionalità è ok da aggiungere a un controllo' e 'questa funzionalità dovrebbe essere inserita nel viewmodel'.

In effetti qui stai semplicemente facendo un controllo composto con una selezione e una vista di dettaglio. Non c'è nulla che lo rende quantitativamente diverso, ad esempio un controllo ComboBox / DropDown.

Ma se vogliamo aggiungere qualche logica personalizzata, diciamo di voler selezionare informazioni extra dal database per l'elemento selezionato. Avere l'oggetto selezionato e un comando ItemSelected sul ViewModel renderà tutto più semplice.

Con WPF hai una serie di opzioni quando si tratta di aggiungere una logica personalizzata.

  • Codice dietro pagina. Puoi gestire eventi e manipolare direttamente i controlli
  • Controlli personalizzati. Puoi sovrascrivere i comportamenti di un controllo, cambiando la sua logica.
  • Comportamenti. Puoi aggiungere comportamenti extra che possono essere collegati a un controllo nella vista
  • Associazione - alla VM. È possibile associare i controlli alle proprietà del relativo contesto dati
  • Associazione - per visualizzare. È possibile eseguire il binding alle proprietà di altri controlli
  • Stili: puoi utilizzare stili e trigger di dati per modificare le proprietà dei controlli
  • Modelli di dati. Puoi personalizzare un controllo con un modello dati
  • Modelli di contenuto. Puoi cambiare il modo in cui un controllo si presenta
  • Convertitori personalizzati. Puoi inserire la logica nei convertitori per cambiare il modo in cui funziona un binding, ad esempio EnumToBrush

Sei sovraccarico di opzioni e funzionano tutte in modi diversi. Ma se stai facendo MVVM prova a favorire il binding a VM e Behavioors

    
risposta data 06.08.2018 - 16:29
fonte
2

Tipicamente, un binding di destinazione SelectedItem appartiene a ViewModel.

Questo perché solitamente vuoi fare qualcosa con SelectedItem (modifica, cancella, ecc.)

Avere l'oggetto SelectedItem sulla VM consente anche di modificare l'oggetto SelectedItem dal codice della macchina virtuale in reazione ad altri eventi nel sistema.

Ora, se questo specifico SelectedItem è solo a scopo di visualizzazione, potresti dimostrare che esso appartiene solo alla vista. Tuttavia, ritengo che questo sia un approccio insolito per il pattern MVVM e posso vedere dove potrebbe essere considerato confuso.

    
risposta data 06.08.2018 - 18:07
fonte
2

The viewmodel doesn't do anything with the selected item. It's only for determining which content is shown in the ContentControl.

Quindi non hai bisogno di una proprietà SelectedItem nel ViewModel. Semplice come quella.

Tuttavia, ciò significa che ora devi assumerti la responsabilità di aggiornare ContentControl nella vista tu stesso usando il codice sottostante, mentre se avessi esposto una SelectedItem sul ViewModel invece, avresti potuto semplicemente usare Linq e dati vincolante per realizzare la stessa cosa nel ViewModel.

Tecnicamente, quali dati decidi di visualizzare in ContentControl è una regola aziendale, non una funzione dell'interfaccia utente. Se è possibile implementare tali regole di business nel ViewModel, è meglio dal punto di vista della manutenzione, poiché la vista non deve preoccuparsi della meccanica dei dati.

    
risposta data 06.08.2018 - 23:29
fonte

Leggi altre domande sui tag