2013-10-29 14 views
34

Ich habe eine WPF-Anwendung mit mehreren Ansichten. Ich möchte von Ansicht 1 zu Ansicht 2 wechseln und von dort kann ich zu mehreren Ansichten wechseln. Ich möchte also einen Button in View 1, der view2 im selben Fenster lädt.WPF MVVM navigieren Ansichten

Ich habe diese Dinge versucht, aber kann es nicht zur Arbeit bringen.

Von der ersten Verbindung das Problem ist, dass ich die viewmodellocator Code nicht verstehen. Sie rufen CreateMain() auf; Funktion, aber wo ist das definiert, und wie kann ich von einer Ansicht auf eine andere Ansicht wechseln.

+1

@ AndrasSebö, bei dieser Gelegenheit stimme ich Ihnen nicht zu. Während ich akzeptiere, dass dies keine große Frage ist, habe ich viel schlechter gesehen und ich glaube, dass es ziemlich klar ist, wonach der Benutzer sucht. – Sheridan

+2

Nun die Frage ist: Wie kann ich die Ansicht von innerhalb einer Ansicht wechseln. – user2499088

+1

Haben Sie einen guten Weg gefunden, dieses Problem anzugehen? – User1551892

Antwort

6

Als ich mit MVVM angefangen habe, hatte ich auch Probleme mit den verschiedenen MVVM-Frameworks und vor allem dem Navigationsteil. Deshalb benutze ich dieses kleine Tutorial das ich gefunden habe, das Rachel Lim erstellt hat. Es ist sehr nett und gut erklärt.

Werfen Sie einen Blick auf sie auf den folgenden Link:

Hoffe, es hat Ihnen geholfen :)

+1

Danke, aber das ist nicht was ich meine. Ich habe dieses Beispiel für eine andere Anwendung verwendet, aber für diese Anwendung habe ich kein Seitenmenü. Also habe ich eine Taste auf view1 und wenn ich auf diese Schaltfläche klicke, muss sie zu view2 wechseln – user2499088

87

Erstens brauchen Sie nicht eine dieser Toolkits/Frameworks um MVVM zu implementieren. Es kann so einfach sein wie dies ... angenommen, wir haben eine MainViewModel, und PersonViewModel und eine CompanyViewModel, jede mit ihrer eigenen verwandten Ansicht und jeder erweitert eine abstract Basisklasse BaseViewModel.

In BaseViewModel können wir gemeinsame Eigenschaften und/oder ICommand Instanzen hinzufügen und die INotifyPropertyChanged Schnittstelle implementieren. Da sie alle BaseViewModel Klasse erweitern, können wir diese Eigenschaft in der MainViewModel Klasse, die zu einem unserer Ansicht Modelle können eingestellt werden:

public BaseViewModel ViewModel { get; set; } 

Natürlich würden Sie die INotifyPropertyChanged Schnittstelle auf korrekt Implementierung werden Ihre Eigenschaften im Gegensatz zu diesem schnellen Beispiel. Jetzt in App.xaml wir einige einfache DataTemplate s erklären, die Ansichten mit den Ansicht Modelle zu verbinden:

<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> 

jetzt, wo wir eine unserer BaseViewModel Instanzen in unserer Anwendung zu verwenden, diese DataTemplate s wird den Rahmen sagen, die angezeigt werden verwandte Ansicht stattdessen. Wir können sie wie folgt angezeigt:

<ContentControl Content="{Binding ViewModel}" /> 

So alles, was wir jetzt auf eine neue Ansicht wechseln tun müssen, die ViewModel Eigenschaft aus der MainViewModel Klasse zu setzen:

ViewModel = new PersonViewModel(); 

Schliesslich, wie wir Ändern Sie die Ansichten von anderen Ansichten? Nun, es gibt mehrere Möglichkeiten, dies zu tun, aber der einfachste Weg ist, eine Binding aus der untergeordneten Ansicht direkt zu einer ICommand in der MainViewModel hinzuzufügen.Ich benutze eine angepasste Version des RelayComand, aber Sie jede Art verwenden können, die Sie mögen und ich nehme an, dass Sie das Bild bekommen:

public ICommand DisplayPersonView 
{ 
    get { return new ActionCommand(action => ViewModel = new PersonViewModel(), 
     canExecute => !IsViewModelOfType<Person>()); } 
} 

In der untergeordneten Ansicht XAML:

<Button Command="{Binding DataContext.DisplayPersonView, RelativeSource= 
    {RelativeSource AncestorType={x:Type MainView}}, Mode=OneWay}" /> 

Das ist es! Genießen.

+0

Ich denke, das wird funktionieren. Aber wenn ich ViewModel = new ... mache, bekomme ich den Fehler "ViewModel ist eine Eigenschaft, wird aber als Typ verwendet" – user2499088

+1

Haben Sie den Typ der 'ViewModel' -Eigenschaft auf' BaseViewModel' eingestellt und lassen Sie Ihre Ansichtsmodelle alle erweitern diese Klasse? – Sheridan

+1

Nun, ich benutze MVVM Light, so dass alle auf ViewModelBase gesetzt sind, aber alle Viewmodels erweitern diese Klasse, und die Eigenschaft hat den Typ ViewModelBase – user2499088

1

Vielleicht this Link wird Ihnen helfen. Setzen Sie einfach die Eigenschaft NavigateTo auf die Ansicht, die Sie im Fenster anzeigen müssen.

Als Beispiel Sie so etwas wie

<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> 

Dann wird die Klassendatei

public partial class MainWindowView : Window 
{ 
    public MainWindowView() 
    {   
       InitializeComponent(); 
    } 

     public ContentControl ViewContainer { get { return _viewContainer; } } 

    } 

Dann können Sie jede Ansicht als UserControl und dann auf den Link ich oben gab die Bindung unter Verwendung definieren würde tun können Knopf meffed:NavigationExtensions.NavigateTo="secondView". Um die ContentControl der Window zu zielen, verwenden Sie einfach eine RelativeSource Bindung. Für z

meffed:NavigationExtensions.NavigationHost="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},Path=ViewContainer}"

In jedem der Ansicht nur sehen, dass Sie den Code hinter Klassendefinition mit den [NavigationView("firstview")] und so weiter mit Anmerkungen versehen.

Es ist kompliziert für das erste Mal, aber es wird sehr einfach sein, wenn Sie die Idee verstehen.

0
<ContentControl x:Name="K.I.S.S" Content="{Binding ViewModel, Converter={StaticResource ViewLocator}}"/>