2011-12-28 14 views

Respuesta

1

Según MVVM pattern ViewModel no tiene conocimiento de la Vista, por lo que no es aceptable. Para interactuar con ViewModel View podría desencadenar un comando, también puede usar enlaces. Además, no debe mover elementos específicos de la interfaz de usuario como BusyIndicator al nivel de ViewModel.

Proporcione más detalles respecto a su caso de uso concreto: cuando desee llamar al método de una Vista y qué hace este método.

+0

Mi UI tiene un indicador "Ocupado" que solo se puede iniciar a través del código subyacente porque se deriva de un control de usuario que tiene esta funcionalidad. Así que necesito el modelo de vista para configurar este indicador de ocupado, ya que es el que trata de obtener los datos del servidor – foreyez

+0

¿Puedes intentar declarar BusyInduicator en XAML y configurar enlaces a propiedades de ViewModel? ¿Cómo exactamente ViewModel debería configurar este indicador? ¿Puedes mostrar el código de inicialización de BudyIndicator con un ViewModel? Además, no debería mover cosas específicas de UI como BusyIndicator al nivel de ViewModel – sll

0

Vi cómo respondiste a la respuesta anterior, estás diciendo que quieres que tu ViewModel recupere datos y luego le dices a tu vista que pare el indicador de ocupado.

No estoy seguro de si mi solución sería la mejor solución, pero puede intentarlo, y quizás alguien pueda corregirla si me equivoco.

Por lo tanto, desde su punto de vista, llamaría a un método de ViewModel para comenzar a leer el conjunto de datos, ¿verdad? En este método, puede pasar un delegado (apuntando a un método que existe en su vista) y cuando su ViewModel termine de leer el conjunto de datos del servidor, active el delegado (desde su viewmodel) que está vinculado a su método en su vista que puede detener el indicador de ocupado

por lo que en su opinión que tienen

void StopBusyIndicator() 
{ 
    this.BusyIndicator.IsBusy = false; 
} 

y cuando llama a un modelo de vista para leer datos,

llamada así:

ViewModel.ReadDataSet(()= >StopBusyIndicator) 

que pasará el método StopBusyIndicator como un delegado, al que puede llamar al final de su ReadDataSet.

HTH

0

Se podría escribir una clase de acción que acepta un objeto de transferencia de datos. Dentro del DTO, agregue una propiedad llamada "Ver" y asígnele la vista actual. Llame la acción a través del controlador desde el código de su vista detrás, desmarque el DTO y ahora tiene el control total de la vista dentro de la clase de acción.

Si realmente quiere hacer esto en su modelo, simplemente cree el método con un parámetro de tipo "Ver" en su Modelo y ejecútelo, pasando en la vista actual.

15

Mi (y tal vez otros?) Dificultad con MVVM fue entender algo simple: Ver sabe sobre ViewModel. Estaba usando enlaces y comandos, pero son simples strings en xaml. Debido a la resolución segura en tiempo de ejecución (seguro significa que puede hacer un error tipográfico, pero el software no se bloquea) esto hace que se vea desacoplado del modelo de vista (al menos en tiempo de compilación). Y siempre estaba buscando una solución para mantener este desacoplamiento, por ejemplo, los comportamientos.

La verdad es que usted puede tener acceso directamente a la vista del modelo, que es típicamente un DataContext de la ventana/control de usuario:

var vm = (MyViewModel)this.DataContext; 

Sabiendo eso, el uso de eventos probablemente la mejor manera de llamar a la vista método de vista del modelo , porque el modelo de vista no sabe si hay suscriptor, solo dispara ese evento y el evento puede ser utilizado por vista u otro modelo de vista.

// define in the view model 
public delegate void MyEventAction(string someParameter, ...); 
public event MyEventAction MyEvent; 

// rise event when you need to 
MyEvent?.Invoke("123", ...); 

// in the view 
var vm = (MyViewModel)DataContext; 
vm.MyEvent += (someParameter, ...) => ... // do something 
+0

. No parece que la sintaxis sea correcta en su ejemplo. Tengo que cambiarlo mucho para que funcione. – Deantwo

+1

@Deantwo, hace 3 años no usé ['EventHandler '] (https://msdn.microsoft.com/en-us/library/db0etb8x (v = vs.110) .aspx) mucho, ni heredo de 'EventArgs' para parámetros ... Reparado errores obvios por el momento, gracias por informar. – Sinatr

1

Puede hacerlo así en Ver (código detrás).

Se aplica a una interfaz que se implementará con ViewModel, para que no esté limitado a un tipo de modelo de vista específico.

// CONSTRUCTOR 
    public SomeView() 
    { 
     InitializeComponent(); 

     DataContextChanged += DataContextChangedHandler; 
    } 

    void DataContextChangedHandler(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     var viewModel = e.NewValue as IInterfaceToBeImplementedByViewModel; 

     if (viewModel != null) 
     { 
      viewModel.SomeEvent += (sender, args) => { someMethod(); } 
     } 
    } 
Cuestiones relacionadas