galasoft - ¿Cuál es la mejor manera de cambiar las vistas/controles de uso en MVVM-light y WPF?
mvvmcross (1)
Lo harías en tu ViewModel padre.
Por ejemplo, si su página ( ViewModelA
PageViewModel
) tenía dos vistas ( ViewModelA
y ViewModelB
), tendría una propiedad en PageViewModel
llamada CurrentView
, y esto determinaría qué Vista es visible. Cuando PageViewModel.CurrentView
se establece en una instancia de ViewModelA
, entonces DataAtemplate de ViewA se usa para dibujar el contenido. Cuando se establece en una instancia de ViewModelB
, se muestra la plantilla de datos de ViewB.
<DataTemplate DataType="{x:Type local:PageViewModel}">
<ContentControl Content="{Binding CurrentView}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelA}">
<TextBlock Text="I''m ViewModelA" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<TextBlock Text="I''m ViewModelB" />
</DataTemplate>
Sería ideal llamar el comando de cambio de vistas desde la vista principal (en este caso, la plantilla de datos para PageViewModel
), sin embargo, si desea cambiar las vistas desde ViewModelA / B, puede conectar el evento manualmente cuando los objetos se creado ( CurrentView.ChangeViewCommand = this.ChangeViewCommand
) o busque en un sistema de mensajería. MVVM Light tiene una clase simple de Messenger
que me pareció bastante fácil de usar o Prism tiene un EventAggregator
más avanzado
Si desea cambiar las vistas para el mismo ViewModel, recomendaría una propiedad de Modo que se use para determinar qué vista usar. Por ejemplo:
<DataTemplate x:Key="ViewA" DataType="{x:Type local:MyViewModel}">
<TextBlock Text="I''m ViewModelA" />
</DataTemplate>
<DataTemplate x:Key="ViewB" DataType="{x:Type local:MyViewModel}">
<TextBlock Text="I''m ViewModelB" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:MyViewModel}">
<ContentControl Content="{Binding }">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource ViewA}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Mode}" Value="2">
<Setter Property="ContentTemplate" Value="{StaticResource ViewB}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
EDITAR
De hecho, veo que este tipo de pregunta surge mucho, así que publique algo al respecto here si alguien está interesado.
Soy relativamente nuevo en WPF y MVVM y lo más difícil que he encontrado es cómo simplemente cambiar un control de usuario o una vista en una aplicación.
En winforms, para que un control se elimine solo dirías esto.Parent.Controls.Remove (this);
En WPF no hay un control genérico de Padres, tendría que encasillarlo al tipo específico (es decir, Grid) y luego eliminarlo.
Esto también parece romper la arquitectura MVVM. También probé las plantillas de datos y los presentadores de contenido, que funcionan bien, excepto por el hecho de que no puedo cambiar el datacontext desde el código, ya que el datacontext es siempre el viewmodellocator.
¿Son las páginas la forma aceptable de hacer esto en WPF ahora? ¿Qué pasaría si tuviera una cuadrícula con un control de usuario personalizado y quisiera cambiarla en función de alguna variable en viewModel? Parece que las tareas más simples no se pueden realizar fácilmente en WPF.