2011-01-05 6 views
30

Tengo un proyecto WPF/Entity Framework (4.0) con muchos objetos. Me gustaría construir la aplicación para que pueda tener el estado de selección de objetos compartido en viewmodels.Ejemplos concretos de compartición de estado entre múltiples modelos de vista (WPF MVVM)

Por ejemplo: Tenemos clases de automóviles, conductores, pasajeros y carga. También tenemos UserControls para CarList, DriverList, etc. y ventanas de edición para CarEditor, DriverEditor, etc. Además, tenemos viewmodels para todos estos (CarListViewModel, DriverListViewModel, CargoEditorViewModel, etc.). Todo esto compone una interfaz acoplable donde el usuario puede tener múltiples listas de objetos, editores y visualizadores abiertos.

Lo que quiero es un ejemplo de código concreto de cómo conectar varios modelos de vista para que seleccionar un coche en CarList haga que ese auto se active en CarEditorView, pero también se seleccione en cualquier otra vista para la que el contexto sea válido (como un DriverByCarView o simplemente DriverList si hay un predicado de filtro).

Hay una serie de sugerencias y debates basados ​​en esta pregunta. Los dos métodos que parecen dominar son:

  • 3018307: Discute el intercambio de estado mencionando un subsistema de mensajería
  • 1159035: Discute el intercambio de estado mediante el uso de un modelo de vista que encierra

es uno de estos enfoques mejor que el otro?

¿Alguien tiene un ejemplo concreto de alguno/ambos de estos métodos en la forma de un proyecto de escritura o código pequeño?

Todavía estoy aprendiendo WPF, por lo que los punteros a los puntos de entrada para leer los fundamentos de la API son apreciados, pero mirando los ejemplos de código es a dónde voy habitualmente.

Gracias


En caso de que a alguien le interesa, aquí hay algunas otras discusiones similares:

  • 3816961: analiza devolver varios ViewModels dependiendo del tipo de objeto (es decir, una colección de tipos arbitrarios que se adhieren a una interfaz específica)
  • 1928130: analiza si es una buena idea agregar modelos de vista como propiedades de otros viewmodels (por ejemplo, una vista MainWindow) modelo compuesto por viewmodels del panel)
  • 1120061: Habla esencialmente de si se debe usar una estrategia de modelo de vista o una estrategia de elemento de vista por elemento.
  • 4244222: Se analiza si se anidan o no los modelos de vista al utilizar una jerarquía de objetos anidados.
  • 4429708: Analiza el intercambio de colecciones entre viewmodels directamente, pero no entra en detalles.
  • List item: describe la administración de selecciones múltiples dentro de un único modelo de vista.
+0

Como adenda sobre los dos primeros artículos vinculados: existe la opinión de que el enfoque de mensajería es válido solo si el estado compartido es entre modelos, no vista; mientras que el modelo de vista adjunto es válido en el otro caso. No estoy seguro si eso es cierto/válido. – JohnMetta

Respuesta

12

Una forma típica de lograr esto es utilizar un messenger para publicar un mensaje CarSelected que detalla el automóvil seleccionado.Cero o más ViewModels pueden suscribirse al mensaje CarSelected. Los ViewModels que están interesados ​​en el automóvil actualmente seleccionado pueden escuchar el mensaje y luego actuar en consecuencia.

El enfoque de mensajería proporciona un diseño desacoplado limpio donde los editores y los suscriptores no tienen dependencias entre sí, por lo que pueden evolucionar fácilmente de forma independiente; solo necesitan saber sobre el mensaje del automóvil. Los mensajeros son una implementación del patrón de mediación.

En Prism, el messenger es EventAggregator y se utiliza para publicar y suscribirse a mensajes.

actualización

Aparte de las ventajas arquitectónicas del EventAggregator trae, también implementa eventos fuertes como para evitar problemas de pérdida de memoria con los abonados que no darse de baja de forma explícita.

consulte el siguiente documentación EventAggregator:

http://msdn.microsoft.com/en-us/library/ff649187.aspx

Prisma:

http://compositewpf.codeplex.com/

Prisma Ejemplo

public class ViewModel1 
{ 
    private readonly IEventAggregator _eventService; 
    private Car _selectedCar; 

    public ViewModel1(IEventAggregator eventService) 
    { 
     _eventService = eventService; 
    } 

    //Databound property... 
    public Car SelectedCar 
    { 
     set 
     { 
      _selectedCar = value; 

      var msg = new CarSelectedMessage { Car = _selectedCar }; 

      _eventService.GetEvent<CarSelectedEvent>().Publish(msg); 
     } 
    } 
} 

public class ViewModel2 
{ 
    public ViewModel2(IEventAggregator eventService) 
    { 
     eventService.GetEvent<CarSelectedEvent>().Subscribe(msg => 
     { 
      //DoStuff with msg... 
     }); 
    } 
} 

public class Car {} 

public class CarMessage 
{ 
    public Car Car { get; set; } 
} 

public class CarSelectedEvent : CompositePresentationEvent<CarMessage> {} 
+0

A pesar de la falta de un puntero a un ejemplo, esto ayuda. Estaba pensando en un patrón de observador en lugar de en un mediador, lo que tiene más sentido. Buscaré en Prism. Gracias. – JohnMetta

+0

@JohnMetta He agregado un par de enlaces para Prism. Es el marco que uso, así que si tienes alguna pregunta, feliz de ayudar. –

Cuestiones relacionadas