Passando parâmetros entre modelos de visão

No meu aplicativo eu tenho 2 visualizações. Lista (GridView) e formulário. Eu estou alterando modos de exibição conforme proposto neste segmento: WPF MVVM switch usercontrols

Agora eu tenho um problema como passar id do item selecionado depois de clicar em editar para mostrar nova visualização com o formulário de edição.

Aplicativo simples para listar todos os itens, adicionar novos, excluir e editar. Como posso fazer isso no MVVWM?


ATUALIZAR

Eu só quero criar um aplicativo simples, que tem menu à esquerda com:

  1. Lista
  2. Adicionar novo.

Quando clica em Lista, mostra UC com lista e 3 botões: Adicionar, Editar, Apagar. Depois de clicar em adicionar, edite-o mostra UC com Formulário com valores específicos (durante a edição). Como posso conseguir isso?

Tanto quanto eu entendo, você quer algo como isto:

Tela principal mostrando a lista Então, quando você clica em Add , mostra isso: Tela principal mostrada no formulário de adição

Certo?

Então você precisa do seguinte comportamento:

  • Adicionar não precisa de nenhum ID.
  • Lista deve recarregar depois de adicionar acabamentos.
  • Editar recebe o ID do item selecionado da lista.
  • Lista deve recarregar depois de adicionar acabamentos.

Eu assumirei que você está trabalhando com algum repository.

Eu proponho a seguinte estrutura MVVM:

  • MainViewModel : O DataContext para a canvas principal.
    • BaseViewModel RightViewModel : O contêiner para BaseViewModel RightViewModel mostrado à direita da canvas.
    • ICommand ViewListCommand : Mostra a lista criando uma nova instância de ListViewModel e atribuindo-a à propriedade BaseViewModel .
    • ICommand AddNewCommand : Mostra a canvas addnew criando uma nova AddViewModel de AddViewModel e atribuindo-a à propriedade BaseViewModel .

Então:

  • ListViewModel : O DataContext para a parte direita da canvas quando Listar é clicado.
    • List Items : Fornece os itens a serem mostrados.
    • Item SelectedItem : a propriedade que será vinculada ao SelectedItem na interface do usuário.
    • ICommand EditCommand : O comando que irá obter o item selecionado e notificar o MainViewModel que deve ser editado.

Então, em algum ponto, um viewmodel receberá uma notificação de um viewmodel filho (ou seja, a lista dirá main para editar alguma coisa). Eu recomendo fazer isso usando events como:

 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; } } 

A binding xaml não é necessária, pois será bastante direta.

Este é um exemplo muito básico sobre como eu acho que esse tipo de coisa pode ser tratada. O importante aqui é desatar adequadamente os events, caso contrário você pode ter problemas.

Para esse tipo de coisa, você também pode dar uma olhada na UI reativa .

Se você tiver um pai comum dos modelos de visualização, poderá usar esse pai para passar valores de parâmetro para você. Basta configurar um ou mais delegate nos modelos de visualização relevantes:

No modelo de visão com o parâmetro relevante para atualizar … vamos chamá-lo ParameterViewModel :

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

No pai:

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

Volta em ParameterViewModel quando o parâmetro muda:

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

Agora no modelo de exibição pai:

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

Você pode descobrir mais sobre como usar objects delegate da página Delegados (guia de programação C #) no MSDN.