Modifica della vista per ViewModel

Sto cercando di implementare il progetto MVVM patern per l’applicazione mt WPF. Per colbind la vista ai modellidisplay, utilizzo un ResourceDictionary (utilizzato in Application.Resources ), che assomiglia

    

I modelli di visualizzazione vengono quindi semplicemente inseriti nei presentatori di contenuto per visualizzarli.

Ora, quando l’utente preme un pulsante, mi piacerebbe visualizzare SampleViewModel usando una vista diversa. Come posso modificare il modello di dati utilizzato per SampleViewModel ?

Meno parole più codice. Per quanto hai detto, hai la class SampleViewModel . Ho aggiunto la proprietà Title for demonstration e ViewType per identificare la vista corretta:

 public enum ItemViewType { View1, View2 }; public class SampleViewModel { public string Title { get; set; } public ItemViewType ViewType { get; set; } } 

DataTemplateSelector per due viste in base alla proprietà ViewType :

 class ItemViewTemplateSelector : DataTemplateSelector { public DataTemplate View1Template { get; set; } public DataTemplate View2Template { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { var vm = item as SampleViewModel; if (vm == null) return null; switch (vm.ViewType) { case ItemViewType.View1: return View1Template; case ItemViewType.View2: return View2Template; } return null; } } 

Codice Xaml:

                 

La parte principale è nella class MainViewModel cui ho messo la logica per cambiare vista:

 public class MainViewModel : ViewModelBase { public MainViewModel() { this.ItemViewModel = new SampleViewModel { Title = "Some title", ViewType = ItemViewType.View1 }; this.SwitchViewCommand = new RelayCommand(() => { this.ItemViewModel.ViewType = this.ItemViewModel.ViewType == ItemViewType.View1 ? ItemViewType.View2 : ItemViewType.View1; //The magic senquence of actions which forces a contentcontrol to change the content template var copy = this.ItemViewModel; this.ItemViewModel = null; this.ItemViewModel = copy; }); } public RelayCommand SwitchViewCommand { get; set; } private SampleViewModel itemViewModel; public SampleViewModel ItemViewModel { get { return itemViewModel; } set { itemViewModel = value; RaisePropertyChanged("ItemViewModel"); } } } 

SwitchViewCommand può essere qualsiasi tipo di comando, io uso il comando dalla libreria mvvmlight.

All’interno del gestore del comando modifico il tipo di viewmodel e ItemViewModel la proprietà ItemViewModel in modo complicato perché un ContentControl aggiorna una vista solo se si modifica la proprietà Content e questa proprietà non verrà modificata a meno che non si imposti un riferimento a un object diverso .

Voglio dire, anche il codice this.ItemViewModel = this.itemViewModel non cambierà la vista. È strano, ma la soluzione non richiede molto lavoro.

È ansible ottenere questo in molti modi diversi dipende dall’architettura che si desidera.

  • Puoi scrivere un DataTemplateSelector personalizzato e usarlo su ContentControl.ContentTemplateSelector e scegliere questi due modelli in modo appropriato
  • Se questo schema di modifica della vista si verifica in molti posti diversi e UX più frequenti, consiglierei anche queste due viste triggerste utilizzando DataTemplate.DataTrigger in base a una proprietà in SampleViewModel [Immagino che potresti avere una proprietà di distinzione nel ViewModel per conoscere quello stato]

È ansible ignorare la mapping posizionando una risorsa simile più in basso nell’albero. Dal momento che WPF risolverà la risorsa cercando verso l’alto, tale sostituzione sostituirà la mapping esistente.