c# - example - Vistas de navegación WPF MVVM
mvvm examples (4)
Cuando comencé con MVVM también tuve problemas con los diferentes frameworks de MVVM y especialmente con la parte de navegación. Por lo tanto uso este pequeño tutorial que encontré, que Rachel Lim ha creado. Es muy lindo y bien explicado.
Míralo en el siguiente enlace:
Espero que te haya ayudado :)
Tengo una aplicación WPF con múltiples vistas. Quiero cambiar de la vista 1 a la vista 2 y desde allí puedo cambiar a varias vistas. Así que quiero un botón en la vista 1 que cargue view2 en la misma ventana.
Intenté esas cosas, pero no puedo hacer que funcione.
- ¿Cómo navegar a través de Windows con MVVM Light para WPF?
- http://blog.galasoft.ch/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx
Desde el primer enlace, el problema es que no entiendo el código viewmodellocator. Llaman a CreateMain (); función, pero dónde se define esto, y cómo puedo cambiar a otra vista desde el interior de una vista.
Quizás this enlace te ayude. Simplemente configure la propiedad NavigateTo
a la vista que necesita mostrar en la ventana.
Como ejemplo puedes hacer algo como
<Window x:Class="MainWindowView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:meffed="http://www.codeplex.com/MEFedMVVM"
meffed:ViewModelLocator.NonSharedViewModel="YourViewModel"
WindowStartupLocation="CenterScreen">
<Button meffed:NavigationExtensions.NavigateTo="firstview"
meffed:NavigationExtensions.NavigationHost="{Binding ElementName=_viewContainer}"
meffed:NavigationExtensions.NavigateOnceLoaded="False"
Visibility="Visible" />
<ContentControl x:Name="_viewContainer" Margin="0,0,0,10" />
<Window>
Entonces el archivo de clase sería
public partial class MainWindowView : Window
{
public MainWindowView()
{
InitializeComponent();
}
public ContentControl ViewContainer { get { return _viewContainer; } }
}
A continuación, puede definir cada vista como UserControl
y, a continuación, utilizando el enlace que di más arriba, meffed:NavigationExtensions.NavigateTo="secondView"
el botón meffed:NavigationExtensions.NavigateTo="secondView"
. Para apuntar al ContentControl
de la Window
simplemente use un enlace RelativeSource
. Por ej.
meffed:NavigationExtensions.NavigationHost="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},Path=ViewContainer}"
En cada vista, simplemente observe que anota el código detrás de la definición de clase con [NavigationView("firstview")]
y así sucesivamente.
Es complicado por primera vez, pero será muy fácil una vez que comprenda la idea.
En primer lugar, no necesita ninguno de esos toolkits / frameworks para implementar MVVM. Puede ser tan simple como esto ... supongamos que tenemos un MainViewModel
, y PersonViewModel
y un CompanyViewModel
, cada uno con su propia vista relacionada y cada uno extendiendo una clase base abstract
BaseViewModel
.
En BaseViewModel
, podemos agregar propiedades comunes y / o instancias de ICommand
e implementar la interfaz INotifyPropertyChanged
. Como todos extienden la clase BaseViewModel
, podemos tener esta propiedad en la clase MainViewModel
que se puede establecer en cualquiera de nuestros modelos de vista:
public BaseViewModel ViewModel { get; set; }
Por supuesto, implementaría la interfaz INotifyPropertyChanged
correctamente en sus propiedades a diferencia de este ejemplo rápido. Ahora en App.xaml
, declaramos algunos DataTemplate
simples para conectar las vistas con los modelos de vista:
<DataTemplate DataType="{x:Type ViewModels:MainViewModel}">
<Views:MainView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:PersonViewModel}">
<Views:PersonView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:CompanyViewModel}">
<Views:CompanyView />
</DataTemplate>
Ahora, donde sea que usemos una de nuestras instancias de BaseViewModel
en nuestra aplicación, estas DataTemplate
le indicarán al marco que muestre la vista relacionada en su lugar. Podemos mostrarlos así:
<ContentControl Content="{Binding ViewModel}" />
Entonces, todo lo que tenemos que hacer ahora para cambiar a una nueva vista es establecer la propiedad ViewModel
de la clase MainViewModel
:
ViewModel = new PersonViewModel();
Finalmente, ¿cómo cambiamos las vistas desde otras vistas? Bueno, hay varias formas posibles de hacerlo, pero la forma más fácil es agregar un Binding
desde la vista secundaria directamente a ICommand
en MainViewModel
. Utilizo una versión personalizada de RelayComand
, pero puede usar cualquier tipo que desee y supongo que obtendrá la imagen:
public ICommand DisplayPersonView
{
get { return new ActionCommand(action => ViewModel = new PersonViewModel(),
canExecute => !IsViewModelOfType<Person>()); }
}
En la vista infantil XAML:
<Button Command="{Binding DataContext.DisplayPersonView, RelativeSource=
{RelativeSource AncestorType={x:Type MainView}}, Mode=OneWay}" />
¡Eso es! Disfrutar.
<ContentControl x:Name="K.I.S.S" Content="{Binding ViewModel, Converter={StaticResource ViewLocator}}"/>