2010-07-15 19 views
13

Tengo una vista que muestra un DataGrid que está vinculado a un ObservableCollection en el modelo de vista. En aras de la discusión, digamos que tenemos una vista Team que contiene un equipo DataGrid, en el que cada fila representa un Player.Múltiples ViewModels asociados con una única vista

Mi pregunta es sobre qué tipo de datos debo usar para representar a los jugadores en mi colección Team. ¿Es una buena idea que los elementos de la colección sean ViewModels mismos? En este caso, mi vista Team se asociaría con un único modelo de vista Team, así como con cualquier número de modelos de vista Player (en la colección de equipos).

¿Tener múltiples ViewModels asociados con una sola vista viola las pautas de diseño para MVVM y existe una forma preferida de implementar este escenario?

Gracias!

Respuesta

28

No, eso está bien; cada objeto debe ser un ViewModel por derecho propio. Hace código más limpio, interacciones más agradables, y recuerda, si funciona bien, entonces es correcto (incluso si viola las pautas).

Lo haría exactamente de la manera que usted está prescribiendo. Me gustaría vincular mi grilla a un Team, que tendría un ObservableCollection<Player>, donde Player es otra clase de tipo ViewModel. Cada elemento de la fila obtendría el Player como su DataContext y por lo tanto usted todavía está vinculando a las propiedades de ViewModel como era de esperar: y Player todavía puede tener propiedades public para ICommand s (Comandos de retransmisión) para la manipulación!

Espero que ayude!

+5

+1 para "si funciona bien, entonces es correcto (incluso si infringe las directrices)" – andyp

+0

No es broma. +1 de mí, también. –

+1

Recibí un jajaja de "si funciona, es correcto", pero he visto muchas cosas que funcionan y están tan lejos de ser correctas que me dan ganas de tirar. :) – CindyH

9

Lejos de violar las directrices, creo que este es el diseño recomendado. Al menos en mis proyectos, verá este patrón repetidamente.

Este patrón es especialmente útil junto con DataTemplates. Por ejemplo, podría definir un DataTemplate en sus Application.Resources para sus PlayerViewModel así:

<DataTemplate DataType="viewModels:PlayerViewModel"> 
    <StackPanel Orientation="Vertical"> 
     <Image Source="/Images/Player.png"/> 
     <TextBlock Text="{Binding Name}"/> 
    </StackPanel> 
</DataTemplate> 

Y luego, si desea mostrar una lista de jugadores que simplemente enlaza un cuadro de lista, etc para su TeamViewModel.Players ObservableCollection y obtener automáticamente el DataTemplate anterior se muestra para cada jugador:

<ListBox ItemsSource="{Binding Players}"/> 
2

Estoy de acuerdo con las dos otras respuestas (las que por Kieren y Groky), pero siento que no mencionan una consideración muy importante en esta decisión.

Solo debe crear un modelo de vista si hay algo específico de la vista sobre lo que está haciendo. Si todo lo que hace es vincular datos e invocar comandos que pertenecen naturalmente a su modelo, no hay razón para crear un modelo de vista.

Por ejemplo, supongamos que:

  1. Su objeto Player tiene una propiedad Name, una propiedad Rango, un método Promover(), y un método de eliminación().
  2. Su vista es simple y le permite editar el nombre y el rango de cualquier jugador, y también tiene botones para promocionar y eliminar jugadores.

En este caso, no tiene sentido agregar un modelo de vista entre su vista y su modelo. Este punto de vista se puede unir directamente al modelo:

  • Enlazar TextBox.Text a la propiedad Name
  • Enlazar Slider.Value a la propiedad Rango
  • Enlazar el botón Promover el método Promover()
  • Enlace el botón Borrar para el método Delete()

Nota que en lugar de unir el botón Borrar para el método de eliminación() es posible que desee establecer su mando a ApplicationCommands.Delete y utilizar un CommandBinding para invocar el Método Delete()

Mi punto aquí es que, en la mayoría de los casos, si sus modelos están bien diseñados, no será necesario insertar un objeto de modelo de vista. Un modelo de vista solo es realmente necesario cuando se debe rastrear un estado específico de la vista (como "Reproductor actual"), las conversiones son demasiado complejas para ser manejadas por un enlace simple o necesita comandos que afectan a varios objetos de modelo y/o vista diferentes. propiedades del modelo al mismo tiempo.

En mi experiencia, si el modelo está diseñado correctamente, solo alrededor del 50% de todas las vistas realmente necesitan un modelo de vista, y en el caso de los elementos de una lista, es más como un 20%.

Un ejemplo de una época en la que puede usar un modelo de vista para un elemento en una lista es cuando necesita mantener una marca "seleccionada" separada que es parte de su vista pero no de su modelo, y la funcionalidad básica en ListBox no es suficiente.

+0

Cita: "Tal vista se puede unir directamente al modelo: Enlazar TextBox.Text a la propiedad Name Enlazar Slider.Value a la propiedad Rank Enlazar el botón Promote con el método Promote()" ¿Desde cuándo? El modelo tiene un método? Enlace el botón Eliminar al método Eliminar() – Elisabeth

+0

Prácticamente todos los modelos tienen métodos. Un modelo sin métodos sería como una persona sin músculos. Sin métodos, ¿cómo le dirías al modelo que haga algo? ¿Reemplazaría 'person.Clap()' con 'person.Clap = true' o' PersonOperations.Clap (person) '? Cualquiera de estos parece torpe en el mejor de los casos. Antes de la programación orientada a objetos había una programación estructurada, en la que se podía crear una función 'PersonClap (Person * person)', pero en mi humilde opinión, la forma de expresar cosas orientada a objetos es mucho más clara. –

+0

La única situación en la que un objeto modelo no tendría métodos es si nunca podría * hacer * nada, sino que era solo un registro de datos brutos. Tales objetos son bastante raros en aplicaciones reales. Posibles ejemplos podrían ser un punto de datos en bruto recibido de un transductor o una entrada bibliográfica, pero incluso estos podrían tener un método Delete(). –

Cuestiones relacionadas