En MVVM, ¿deberían ViewModel o View ser responsables de crear nuevas vistas?

11

En mi aplicación WPF, quiero crear una nueva vista. ¿Dónde debo hacer eso, en ViewModel o Model ?

La aplicación es (muy simple por ahora) una herramienta tipo ventana con un solo botón "enviar". En caso de que se seleccione una de las casillas de verificación, debería aparecer una nueva ventana con el mismo ViewModel para solicitar al usuario algunos detalles adicionales. Para los propósitos de esta pregunta, consideremos solo el nuevo enfoque de ventana sin considerar otros enfoques como el panel mostrado / oculto.

Idealmente, en View no debería haber ningún código. Además, dado que View no tiene ninguna lógica, VM necesitaría inicialmente verificar si se necesita crear una nueva vista y, cuando lo sea, devolver esta responsabilidad a View, lo que lleva a una acumulación de código.

Por otro lado, crear una nueva vista en ViewModel viola el principio de que ViewModel no debería saber nada sobre View.

Entonces, ¿ es mejor crear nuevas vistas en View o ViewModel?

Mac70
fuente
1
Realmente no entiendo tu pregunta. ¿Qué significa "In View o ViewModel"? Los ViewModels no crean vistas, y las vistas ciertamente no se crean a sí mismas.
Robert Harvey
1
Me refiero a cuál de estas capas debería ser responsable de crear nuevas vistas; la señal para hacerlo debe provenir de algún lugar cuando se produce una acción. Excluí completamente el modelo de esta pregunta, porque no debería saber nada sobre frontend.
Mac70
Tal vez no entiendo su pregunta correctamente, ambos no deberían interferir con su punto de vista. Si desea crear una nueva vista en su viewModel, ¿hay alguna razón por la que no esté usando marcos en xaml para cambiar el contenido de la ventana con un enlace a su viewModel actual?
Siobhan

Respuestas:

8

Utilizo la inyección de dependencia y una IViewFactoryinyección en el modelo de vista para respetar ambas restricciones.

A ProductViewModel(por ejemplo) llama this.viewFactory.Show("Details", this)a abrir ProductDetailsViewconsigo mismo como ProductViewModel. También podría abrir una vista basada en otro modelo de vista con this.viewFactory.Show<ClientViewModel>().

La implementación (en realidad hay varios para WinForms, Windows Wpf simple, un shell Wpf con pestañas, ...) se basa en una StructureMapconvención. Las vistas designan su modelo de vista a través de una IView<ProductViewModel>interfaz.

Por lo tanto, el modelo de vista no sabe nada sobre la vista, excepto su función (vista predeterminada, vista de detalles, ...), y la vista no contiene código para crear otra vista. Además, los modelos de vista están en un ensamblaje separado que no hace referencia a ningún ensamblado Wpf.

Philippe
fuente
7

Respuesta teórica

Si tiene un ViewModel, las acciones que tienen efectos cosméticos (por ejemplo, resaltar un elemento al pasar el mouse) son el trabajo del View, mientras que las acciones que tienen efectos "reales" (por ejemplo, generar una nueva ventana) son el trabajo del ViewModel.

Como tal, crear una nueva ventana es un trabajo para ViewModel. Sin embargo, ni la Vista ni la ViewModeldeberían saber exactamente cómo crear una Ventana, eso no es parte de sus responsabilidades y pertenece a una clase diferente.

Se podría argumentar que crear una nueva ventana es un trabajo para el View. Si bien no estoy de acuerdo, hay poco valor en tal debate, porque en la práctica no es el fin del mundo si colocas ese código en el View, y tampoco es mucho trabajo moverlo al ViewModelfuturo. . La parte importante es que la lógica para la creación de una nueva ventana está contenida en una clase independiente, generalmente algún tipo de WindowFactory. El punto de MVVM, MVP, MVC, etc. es que tienes clases con pocas responsabilidades bien definidas. Es por eso que no se agrega responsabilidades adicionales para el View, ViewModelo Modelsi no es necesario.

Bajo ninguna circunstancia pertenece la creación de la Ventana Model, porque Modelni siquiera es consciente de que hay algo como una GUI.

Respuesta práctica

Se trata de una "herramienta de formulario de una ventana con un solo botón" enviar " . Así que aquí hay un enchufe descarado para una respuesta mía relacionada: ¿Por qué usar MVVM?

Para resumir lo que dice esa respuesta: Hazlo simple. Ah, y tenga en cuenta la respuesta teórica anterior para implementar una vez que su ventana de un solo botón comience a volverse más compleja.

Peter
fuente