Actualmente estoy trabajando con la plantilla MVVM de Microsoft y encuentro frustrante la falta de ejemplos detallados. El ejemplo de ContactBook incluido muestra muy poco manejo de comandos y el único otro ejemplo que he encontrado es el de un artículo de MSDN Magazine donde los conceptos son similares pero utilizan un enfoque ligeramente diferente y aún carecen de complejidad. ¿Hay ejemplos de MVVM decentes que al menos muestren operaciones CRUD básicas y cambio de diálogo / contenido?
Las sugerencias de todos fueron realmente útiles y comenzaré a compilar una lista de buenos recursos
Marcos / Plantillas
Artículos utiles
- Aplicaciones WPF con el patrón de diseño Model-View-ViewModel
- Validación de datos en .NET 3.5
- Uso de un modelo de vista para proporcionar mensajes de error de validación significativos
- Validación basada en acciones de ViewModel y Model
- Cuadros de diálogo
- Enlaces de comandos en MVVM
- Más que solo MVC para WPF
- Aplicación de ejemplo de mediador MVVM +
Screencasts
Bibliotecas adicionales
- Implementación mejorada del patrón de mediador de WPF Disciples (lo recomiendo encarecidamente para aplicaciones que tienen navegación más compleja)
- MVVM Light Toolkit Messenger
Respuestas:
Desafortunadamente, no hay una gran aplicación de ejemplo MVVM que haga todo, y hay muchos enfoques diferentes para hacer las cosas. Primero, es posible que desee familiarizarse con uno de los marcos de la aplicación (Prism es una opción decente), ya que le proporcionan herramientas convenientes como inyección de dependencia, comando, agregación de eventos, etc. para probar fácilmente diferentes patrones que le convengan .
El lanzamiento del prisma:
http://www.codeplex.com/CompositeWPF
Incluye una aplicación de ejemplo bastante decente (el operador de bolsa) junto con muchos ejemplos más pequeños y cómo hacerlo. Por lo menos, es una buena demostración de varios subpatrones comunes que las personas usan para hacer que MVVM realmente funcione. Tienen ejemplos para CRUD y diálogos, creo.
Prism no es necesariamente para cada proyecto, pero es bueno familiarizarse con él.
CRUD: esta parte es bastante fácil, los enlaces bidireccionales de WPF hacen que sea muy fácil editar la mayoría de los datos. El verdadero truco es proporcionar un modelo que facilite la configuración de la interfaz de usuario. Como mínimo, desea asegurarse de que su ViewModel (u objeto de negocio) se implemente
INotifyPropertyChanged
para admitir el enlace y puede vincular propiedades directamente a los controles de la interfaz de usuario, pero también puede implementarloIDataErrorInfo
para la validación. Por lo general, si usa algún tipo de solución ORM, configurar CRUD es muy fácil.Este artículo muestra operaciones simples de crud: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx
Está construido en LinqToSql, pero eso es irrelevante para el ejemplo; todo lo que es importante es que sus objetos de negocio implementen
INotifyPropertyChanged
(qué clases generadas por LinqToSql sí). MVVM no es el punto de ese ejemplo, pero no creo que importe en este caso.Este artículo demuestra la validación de datos
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
Una vez más, la mayoría de las soluciones ORM generan clases que ya implementan
IDataErrorInfo
y generalmente proporcionan un mecanismo para facilitar la adición de reglas de validación personalizadas.La mayoría de las veces puede tomar un objeto (modelo) creado por algún ORM y envolverlo en un ViewModel que lo contiene y los comandos para guardar / eliminar, y está listo para vincular la IU directamente a las propiedades del modelo.
La vista se vería así (ViewModel tiene una propiedad
Item
que contiene el modelo, como una clase creada en el ORM):Diálogos: los diálogos y MVVM son un poco complicados. Prefiero usar una idea del enfoque de Mediador con diálogos, puede leer un poco más sobre esto en esta pregunta de StackOverflow:
ejemplo de diálogo WPF MVVM
Mi enfoque habitual, que no es MVVM clásico, se puede resumir de la siguiente manera:
Una clase base para un ViewModel de diálogo que expone comandos para las acciones de confirmación y cancelación, un evento que le permite a la vista saber que un diálogo está listo para cerrarse, y cualquier otra cosa que necesite en todos sus diálogos.
Una vista genérica para su diálogo: puede ser una ventana o un control de tipo de superposición "modal" personalizada. En esencia, es un presentador de contenido en el que volcamos el modelo de vista y maneja el cableado para cerrar la ventana; por ejemplo, en el cambio de contexto de datos, puede verificar si el nuevo ViewModel se hereda de su clase base, y si es así, suscríbase al evento de cierre relevante (el controlador asignará el resultado del diálogo). Si proporciona una funcionalidad de cierre universal alternativa (el botón X, por ejemplo), también debe asegurarse de ejecutar el comando de cierre correspondiente en ViewModel.
En algún lugar donde necesite proporcionar plantillas de datos para sus ViewModels, pueden ser muy simples, especialmente porque probablemente tenga una vista para cada cuadro de diálogo encapsulado en un control separado. La plantilla de datos predeterminada para un ViewModel se vería así:
La vista de diálogo debe tener acceso a estos, porque de lo contrario no sabrá cómo mostrar el ViewModel, aparte de la interfaz de usuario del diálogo compartido, su contenido es básicamente el siguiente:
La plantilla de datos implícitos asignará la vista al modelo, pero ¿quién la inicia?
Esta es la parte no tan mvvm. Una forma de hacerlo es usar un evento global. Lo que creo que es mejor hacer es usar una configuración de tipo de agregador de eventos, proporcionada mediante inyección de dependencia, de esta manera el evento es global para un contenedor, no para toda la aplicación. Prism utiliza el marco de la unidad para la semántica de contenedores y la inyección de dependencia, y en general me gusta bastante Unity.
Por lo general, tiene sentido que la ventana raíz se suscriba a este evento: puede abrir el cuadro de diálogo y establecer su contexto de datos en ViewModel que se pasa con un evento generado.
Configurar esto de esta manera permite que ViewModels solicite a la aplicación que abra un cuadro de diálogo y responda a las acciones del usuario allí sin saber nada acerca de la interfaz de usuario, por lo que la mayor parte de la MVVM-ness permanece completa.
Sin embargo, hay momentos en que la interfaz de usuario tiene que abrir los diálogos, lo que puede hacer las cosas un poco más complicadas. Considere, por ejemplo, si la posición del diálogo depende de la ubicación del botón que lo abre. En este caso, debe tener información específica de la IU cuando solicite que se abra un cuadro de diálogo. Por lo general, creo una clase separada que contiene un ViewModel y alguna información relevante de la interfaz de usuario. Desafortunadamente, algunos acoplamientos parecen inevitables allí.
Seudocódigo de un controlador de botones que genera un diálogo que necesita datos de posición del elemento:
La vista de diálogo se unirá a los datos de posición y pasará el ViewModel contenido al interior
ContentControl
. ViewModel en sí todavía no sabe nada sobre la interfaz de usuario.En general, no uso la
DialogResult
propiedad return delShowDialog()
método ni espero que el hilo se bloquee hasta que se cierre el cuadro de diálogo. Un cuadro de diálogo modal no estándar no siempre funciona así, y en un entorno compuesto a menudo no desea que un controlador de eventos bloquee así de todos modos. Prefiero dejar que los ViewModels se ocupen de esto: el creador de un ViewModel puede suscribirse a sus eventos relevantes, establecer métodos de confirmación / cancelación, etc., por lo que no es necesario confiar en este mecanismo de interfaz de usuario.Entonces, en lugar de este flujo:
Yo suelo:
Lo prefiero de esta manera porque la mayoría de mis cuadros de diálogo son controles pseudo-modales que no bloquean y hacerlo de esta manera parece más sencillo que evitarlo. Prueba fácil de unidad también.
fuente
Jason Dolinger hizo un buen screencast de MVVM. Como Egor mencionó, no hay un buen ejemplo. Están por todas partes. La mayoría son buenos ejemplos de MVVM, pero no cuando tienes problemas complejos. Todos tienen su propio camino. Laurent Bugnion también tiene una buena forma de comunicarse entre modelos de vista. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch también es un buen ejemplo. Paul Stovel tiene una buena publicación que explica mucho también con su marco Magellan.
fuente
¿Has mirado a Caliburn ? La muestra de ContactManager contiene muchas cosas buenas. Los ejemplos genéricos de WPF también proporcionan una buena visión general de los comandos. La documentación es bastante buena y los foros están activos. ¡Recomendado!
fuente
Encontré este útil. Tiene código también.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
fuente
Aquí estoy agregando el enlace de una aplicación WPF (Inventory Management App) que utiliza la arquitectura MVVM diseñada por mí.
Su interfaz de usuario es impresionante. https://github.com/shivam01990/InventoryManagement
fuente
El proyecto de muestra en el marco de Cinch muestra CRUD básico y herramientas de navegación. Es un buen ejemplo de uso de MVVM e incluye un artículo de varias partes que explica su uso y motivaciones.
fuente
También compartí tu frustración. Estoy escribiendo una solicitud y tenía estos 3 requisitos:
Todo lo que encontré fueron pedazos, así que comencé a escribirlo lo mejor que pude. Después de analizarlo un poco, me di cuenta de que podría haber otras personas (como usted) que podrían usar una aplicación de referencia, así que refactoricé el material genérico en un marco de aplicación WPF / MVVM y lo lancé bajo la LGPL. Lo llamé SoapBox Core . Si va a la página de descargas, verá que viene con una pequeña aplicación de demostración, y el código fuente de esa aplicación de demostración también está disponible para descargar. Espero que lo encuentres útil. Además, envíeme un correo electrónico a scott {at} soapboxautomation.com si desea obtener más información.
EDITAR : También publicó un artículo de CodeProject que explica cómo funciona.
fuente
He escrito un ejemplo simple de MVVM desde cero en el proyecto de código, aquí está el enlace MVVM WPF paso a paso . Comienza desde una arquitectura simple de 3 capas y lo gradúa para usar un marco como PRISM.
fuente
Incluso compartí la frustración hasta que tomé el asunto en mis manos. Empecé IncEditor.
IncEditor ( http://inceditor.codeplex.com ) es un editor que intenta presentar a los desarrolladores WPF, MVVM y MEF. Lo comencé y logré obtener algunas funcionalidades como soporte de 'tema'. No soy un experto en WPF o MVVM o MEF, así que no puedo ponerle mucha funcionalidad. Les pido sinceramente que mejoren para que los locos como yo puedan entenderlo mejor.
fuente