Passando i parametri tra viewmodels

Nella mia app ho 2 visualizzazioni. Elenco (GridView) e modulo. Sto cambiando le visualizzazioni come proposto in questo thread: WPF MVVM switch usercontrols

Ora ho un problema su come passare l’id dell’elemento selezionato dopo aver fatto clic su modifica per mostrare una nuova vista con il modulo di modifica.

Semplice applicazione per elencare tutti gli articoli, aggiungere nuovi, cancellare e modificare. Come posso farlo in MVVWM?


AGGIORNARE

Voglio solo creare una semplice applicazione, che ha un menu a sinistra con:

  1. Elenco
  2. Aggiungere nuova.

Quando fai clic su Elenco, mostra UC con elenco e 3 pulsanti: Aggiungi, Modifica, Elimina. Dopo aver fatto clic su Aggiungi, modifica mostra UC con Form con valori specifici (durante la modifica). Come posso raggiungere questo objective??

Per quanto ho capito, vuoi qualcosa del genere:

Schermata principale che mostra la lista In modo che quando si fa clic su Add , questo mostra: La schermata principale mostra il modulo di aggiunta

Destra?

Quindi hai bisogno del seguente comportamento:

  • Aggiungi non ha bisogno di alcun ID.
  • L’elenco deve essere ricaricato dopo aver completato Aggiungi.
  • Modifica riceve l’ID object selezionato dell’elenco.
  • L’elenco deve essere ricaricato dopo aver completato Aggiungi.

Assumerò che stai lavorando con qualche repository.

Propongo la seguente struttura MVVM:

  • MainViewModel : DataContext per la schermata principale.
    • BaseViewModel RightViewModel : il contenitore per i modelli di visualizzazione mostrato nella parte destra dello schermo.
    • ICommand ViewListCommand : mostra l’elenco creando una nuova istanza di ListViewModel e assegnandola alla proprietà BaseViewModel .
    • ICommand AddNewCommand : mostra la schermata di aggiunta creando una nuova isntance di AddViewModel e assegnandola alla proprietà BaseViewModel .

Poi:

  • ListViewModel : DataContext per la parte destra dello schermo quando si fa clic su Elenco.
    • List Items : fornisce gli elementi da mostrare.
    • Item SelectedItem : la proprietà che verrà associata a SelectedItem sull’interfaccia utente.
    • ICommand EditCommand : il comando che otterrà l’elemento selezionato e notificherà il MainViewModel che deve essere modificato.

Quindi, ad un certo punto, un viewmodel riceverà una notifica da un viewmodel figlio (ad esempio la lista dirà al principale di modificare qualcosa). Raccomando di farlo usando eventi come:

 public class Item { public string Name { get; set; } } public class ItemEventArgs : EventArgs { public Item Item { get; set; } public ItemEventArgs(Item selectedItem) { this.Item = selectedItem; } } public class BaseViewModel { } public class ListViewModel : BaseViewModel { public event EventHandler EditItem; public Item SelectedItem { get; set; } public ICommand EditItemCommand { get; private set; } public ListViewModel() { this.EditItemCommand = new DelegateCommand(() => this.EditItem(this, new ItemEventArgs(this.SelectedItem))); } } public class EditViewModel : BaseViewModel { } public class MainViewModel { public BaseViewModel RightViewModel { get; private set; } public ICommand ViewListCommand { get; private set; } public MainViewModel() { this.ViewListCommand = new DelegateCommand(() => { // unhook possible previous events var listViewModel = new ListViewModel(); listViewModel.EditItem += listViewModel_EditItem; this.RightViewModel = listViewModel; }); } void listViewModel_EditItem(object sender, ItemEventArgs e) { // unhook possible previous events var editViewModel = new EditViewModel(); this.RightViewModel = editViewModel; } } 

Il legame xaml non è necessario poiché sarà piuttosto avanti.

Questo è un esempio di base su come penso che questo tipo di cose possa essere gestito. La cosa importante qui è di sganciare correttamente gli eventi, altrimenti potresti incorrere in problemi.

Per questo genere di cose puoi anche dare un’occhiata all’interfaccia utente retriggers .

Se hai un genitore comune dei modelli di visualizzazione, puoi utilizzare quel genitore per passare i valori dei parametri per te. È sufficiente configurare uno o più delegate nei relativi modelli di visualizzazione:

Nel modello di vista con il parametro rilevante da aggiornare … chiamiamolo ParameterViewModel :

 public delegate void ParameterChange(string parameter); public ParameterChange OnParameterChange { get; set; } 

Nel genitore:

 ParameterViewModel viewModel = new ParameterViewModel(); viewModel.OnParameterChange += ParameterViewModel_OnParameterChange; ListMenu.Add(viewModel); // Add other view models 

Indietro in ParameterViewModel quando il parametro cambia:

 public string Parameter { get { return parameter; } set { parameter = value; NotifyPropertyChanged("Parameter"); // Always check for null if (OnParameterChange != null) OnParameterChange(parameter); } } 

Ora nel modello di visualizzazione genitore:

 public void ParameterViewModel_OnParameterChange(string parameter) { // Do something with the new parameter data here AnotherViewModel anotherViewModel = (AnotherViewModel)ListMenu[someIndex]; anotherViewModel.Parameter = parameter; } 

Puoi trovare ulteriori informazioni sull’utilizzo degli oggetti delegate dalla pagina Delegati (Guida alla programmazione C #) su MSDN.