2009-04-02 6 views
9

Tenía una pregunta sobre las responsabilidades de VM cuando se trata de ventanas emergentes. Cuando una aplicación está apareciendo un cuadro de mensaje o algún tipo de diálogo (con MVVM), las dos opciones que tenemos son:Forma correcta de mostrar ventanas emergentes mediante el patrón WPF M-V-VM

  1. poner la interfaz de usuario (ShowDialog()) código de máquina virtual que parece mal
  2. tienen VM envía algún tipo de evento al que la IU puede suscribirse y muestra un cuadro de diálogo en el código subyacente (pero estamos luchando por cero código detrás :))

¿Cómo pueden abordar este caso?

+0

Me pregunto si este hilo ayudará. [http://stackoverflow.com/questions/454868/handling-dialogs-in-wpf-with-mvvm](http://stackoverflow.com/questions/454868/handling-dialogs-in-wpf-with-mvvm) – djcouchycouch

Respuesta

2

No coloque el código de UI en la VM, que solo causa muchos dolores de cabeza en el futuro.

Por lo general, tiene dos casos cuando desea abrir una ventana o un diálogo. O lo haces por un caso comercial, p. una vista de detalle al hacer doble clic en una lista, o está completamente basada en la interfaz de usuario, p. apareciendo una ventana de opciones. En el primer caso, es mejor utilizar un evento en la VM, en el caso posterior solo uso un controlador de eventos. Una buena regla general es que, si no necesita ninguna variable de VM (significativa) para llevar a cabo la acción, entonces debe usar un controlador de eventos.

Sobre todo, use su cabeza y confíe en su juicio, aprenderá qué usar lo suficientemente pronto.

0

Uso los eventos que maneja la vista. No me gusta al 100%, pero permite las pruebas automatizadas.

0

Cree una interfaz para su cuadro de diálogo emergente incluso si planea usar messagebox.

En la parte inferior de una vista de la jerarquía de su vista, tenga un método para que el presentador registre la clase o el formulario que implementa la ventana emergente.

Haga que sus vistas llamen a la ventana emergente registrada.

1

Un par de otras opciones que no se mencionan por otros:

un comando de retransmisión

La máquina virtual ejecuta un comando que me gusta llamar un "relay comando". Es un comando manejado por otra persona y a la VM no le importa quién. La ejecución del comando no hace más que plantear el evento Executed. Su vista se suscribiría a este evento y mostraría el contenido en un nuevo Window (el contenido se pasaría como el parámetro de comando).

Tenga en cuenta que un comando de retransmisión no es un comando enrutado. No busca un controlador en su lógica de ejecución. Simplemente plantea un evento.

Un servicio

Si hay una gran cantidad de casos donde se necesita mostrar algo en una ventana, escribir un servicio de interfaz de usuario que se encarga de ello. Las máquinas virtuales luego dependen de este servicio (que se puede burlar fácilmente) para mostrar contenido en Windows.

1

yo diría que el mejor camino a seguir es definir el Popup en XAML y luego usar un DataTrigger con destino a alguna condición en su ViewModel para ocultar o mostrar la misma.Luego, si le importa manejar un valor devuelto por Popup, tenga un EventTrigger en el Popup manipule las propiedades ViewModel para reflejar ese cambio.

Se habla mucho de este tipo de área, y creo que se debe a que la gente está acostumbrada a programar en un mundo WinForms. Aún no he encontrado una solución donde necesite ningún código en la vista que no sea para recuperar datos iniciales o establecer DataContexts

0

Estoy de acuerdo con Carlos en que usar suscripción a eventos en la vista no es una buena opción. Por lo que yo entiendo MVVM, lleva a eliminar cualquier código detrás de la vista y realmente me gusta :). Una de las ventajas del MVVM es la capacidad de probarlo por unidades. Pero sigo creyendo que el modelo de vista puede probarse incluso si aparece una ventana emergente. Todo lo que necesitamos es usar Window con Contenido inicializado con el modelo de vista necesario. Creo que podría haber 2 situaciones posibles cuando VM debería abrir un nuevo cuadro de diálogo: ya sea para mostrar la ventana de opciones/configuración o para mostrar una ventana que depende de la lógica comercial. En el primer caso, el código de la nueva ventana es el único código del comando (comando para 'Configuración' u 'Opciones' botón/elemento de menú). En el segundo caso, tenemos alguna lógica de toma de decisiones que abre la ventana. Pero en cualquier caso, podemos mover el código que abre una nueva ventana a un método/clase por separado y al probar nuestra VM para simular este método/clase. Aún más, esta clase separada puede ser algún tipo de WindowsController genérico que hará un seguimiento de todas las ventanas en la aplicación. Pero aún podemos decir que el modelo de vista abre ventana emergente usando el controlador WindowsController y la vista no sabe nada más sobre otras ventanas. Toda la lógica comercial permanece encapsulada en modelo y modelo de vista.

0

Tiene un ViewModel para ventana emergente y Ver como control de usuario. Dependiendo de la complejidad de la ventana emergente, puede ser VM universal o VM concreta para el caso de negocios. Cuando intente mostrarlo desde la máquina virtual primaria, cree una clase "host" para la máquina virtual de ventanas emergentes (heredada de Ventana o Ventana emergente), muéstrela y asigne la máquina virtual a ella. El host debe tener la responsabilidad de ubicar la vista adecuada (por ejemplo, a través de DataTemplate)

En este caso, la VM de su ventana emergente aún se puede probar y el nivel mínimo de acoplamiento con WPF para la máquina virtual principal es aceptable, IMO.

2

Echa un vistazo Onyx. Esta es una biblioteca M-V-VM (divulgación completa: soy el autor) basada en el uso de servicios y el Localizador de servicios o los patrones de Inyección de dependencias. Hay servicios para MessageBox y diálogos comunes, y es muy fácil agregar sus propios servicios también.

Cuestiones relacionadas