2009-12-05 13 views
5

Estoy tratando de aprender el patrón MVVM. El principal problema que tengo es aprender dónde debo declarar, crear y vincular objetos de comando.Encuadernación de comandos MVVM

2 ejemplos:

  1. que tienen un formulario principal que actúa como un tablero de interruptor o al menú principal. Se muestra el botón selct 1 y la vista 1, se muestra el botón Select 2 y la vista 2. Estupendo. Ahora quiero volver al formulario principal, así que necesito un botón en la Vista 1 (y vista 2) llamado "Menú principal". ¿Dónde debería definir el comando y los manejadores de comandos para poder enlazar con el comando "ShowMainMenu"? ¿Podría crearlos en View2ViewModel pero luego no tengo acceso para mostrar la vista principal? O bien, podría crear Thim en el modelo MainView, pero luego ¿Cómo puedo enlazarlos en el modelo de vista secundaria (estoy usando el comando RelayCommand según la recomendación mvvm y no aparecen en el padre)

  2. Tengo dos controles de usuario visibles en una sola ventana principal, llamémoslos MainView, UC1 y UC2. cada uno de estos tiene ViewModel MainViewModel, UC1ViewModel, UC2View Model. Tengo un botón en UC1 llamado "AddItem". Debería agregar un elemento en una lista en UC2. ¿Cuál es la forma correcta de configurar un "AddItemCommand" y vincularse a él. ¿Debería estar el comando en MainViewModel, Uc1ViewModel o UC2ViewModel? Y cómo debo atarlo.

Gracias por su ayuda.

Respuesta

3

1) Puede heredar View1Model y View2Model desde un ViewModel base y definir ShowMainMenu allí.

o (es mi enfoque)

Crear RootView con ContentPresenter que mostrará todos sus puntos de vista. Cree RootVeiwModel con la propiedad ViewContent. Vincula propiedad del contenido de ContetnPresenter a la propiedad ViewContent de RootViewModel. Puede usar object como tipo de contenido de vista, pero le aconsejo que defina la interfaz compatible con MainVView1Model, View1Model y View2Model. El cambio de ViewContent debe generar ProprtyChangedEvent. Defina ShowMainViewCommand en RootViewModel, que simplemente cambiará ViewContent a MainViewModel (y se mostrará como MainView). Luego rem Comando propiedad de Button en View1 y Vista2 a ese comando, para de esa manera exmple:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RootView}}, 
         Path=DataContext.ShowMainViwe} 

Hay algo de código para explicar lo que estoy tratando de decir:

RootView.xaml

... 
<ContentPresenter Content={Binding ViewContent} /> 
... 

RootViewModel.ca

class RootViewModel : INotifyPropertyCahnged 
{ 
    ... 
    private object _ViewContent; 
    public object ViewContent 
    { 
     get {return _ViewContent;} 
     set 
     { 
      _ViewContent = value; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged ("ViewContent"); 
      } 

     } 
    } 

    private RelayCommand _ShowMainView; 
    public ICommand ShowMainView 
    { 
     get 
     { 
      if (_ShowMainView == null) 
      { 
       _ShowMainView = new RelayCommand(x => ViewContent = new MainViewModel()); 
      } 
      return _ShowMainView; 
     } 
    } 
    ... 
} 

2) Añadir referencia a MainViewModel a UC1ViewModel y UC2ViewModel - esa es la manera de influir en otros controles. MainViwModel debe contener propiedades que contengan UC1ViewModel y UC2ViewModel. Los elementos del segundo control de usuario deben estar en ObservableCollection.

te acabo de mostrar cómo funciona el código:

class UC1ViewModel : INotifyPropertyChanged 
{ 
    ... 
    private MainViewModel _Parent; 
    public UC1ViewModel(MainViewModel parent) 
    { 
     _Panert = parent; 
    } 

    private RelayCommand _AddItemToUC2; 
    public ICommand AddItemToUC2 
    { 
     get 
     { 
      if (_AddItemToUC2 = null) 
      { 
       // UC2Content is UC2ViewModel 
       // Items is ObservableCollection 
       _AddItemToUC2 = new RelayCommand(x => _Parent.UC2Content.Items.Add(...)); 
      } 
      return AddItemToUC2; 
     } 
    } 
    ... 
} 
+0

En la primera exmaple configura ViewContent = new MainViewModel()); ¿Se supone que esto es un control de ventana/usuario? ¿O realmente configura el contenido actual para un modelo de vista? – thrag

+0

Es modelo de vista. Si coloca ContentPresenter en su vista y vincula la propiedad Content a ViewModel, se mostrará como vista asociada. ¿Utiliza asociación view-viewmodel como esta: bniwredyc

2

MainModel podría tener una propiedad para cada UCxViewModel o, más fácil, una lista de ViewModels. El comando "Mostrar" crearía un modelo UVxView correspondiente, suscribirse a un evento "OnClose" publicado por UVxViewModel, y agregarlo a la lista. MainView tiene un control (por ejemplo, Control de pestañas) vinculado a esta lista y DataTemplates define las Vistas que se utilizarán para cada UCxViewModel. Cuando el modelo UVxView activa su evento OnClose, MainModel lo quita de la lista, haciendo que la vista correspondiente se "cierre".

Para la parte "Agregar elemento", los ViewModels deben compartir la misma lista de elementos (el Modelo). El UC2ViewModel puede agregar un elemento y UC1View se actualizará (siempre que la lista implemente INotifyCollectionChanged).

Encontré this explanation muy útil para comprender MVVM.

Cuestiones relacionadas