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?
Respuestas:
Utilizo la inyección de dependencia y una
IViewFactory
inyección en el modelo de vista para respetar ambas restricciones.A
ProductViewModel
(por ejemplo) llamathis.viewFactory.Show("Details", this)
a abrirProductDetailsView
consigo mismo comoProductViewModel
. También podría abrir una vista basada en otro modelo de vista conthis.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
StructureMap
convención. Las vistas designan su modelo de vista a través de unaIView<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.
fuente
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 delView
, mientras que las acciones que tienen efectos "reales" (por ejemplo, generar una nueva ventana) son el trabajo delViewModel
.Como tal, crear una nueva ventana es un trabajo para
ViewModel
. Sin embargo, ni la Vista ni laViewModel
deberí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 elView
, y tampoco es mucho trabajo moverlo alViewModel
futuro. . 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 elView
,ViewModel
oModel
si no es necesario.Bajo ninguna circunstancia pertenece la creación de la Ventana
Model
, porqueModel
ni 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.
fuente