it-swarm.com.de

WPF MVVM-Navigationsansichten

Ich habe eine WPF-Anwendung mit mehreren Ansichten. Ich möchte von Ansicht 1 zu Ansicht 2 wechseln und von dort aus kann ich zu mehreren Ansichten wechseln. Ich möchte also eine Schaltfläche in Ansicht 1, die Ansicht 2 im selben Fenster lädt.

Ich habe diese Dinge ausprobiert, kann sie aber nicht zum Laufen bringen.

Vom ersten Link an besteht das Problem darin, dass ich den ViewModelLocator-Code nicht verstehe. Sie rufen die Funktion CreateMain(); auf, aber wo ist dies definiert und wie kann ich aus einer Ansicht heraus zu einer anderen Ansicht wechseln?.

41
user2499088

Erstens benötigen Sie keines dieser Toolkits/Frameworks, um MVVM zu implementieren. So einfach kann das sein ... Nehmen wir an, wir haben eine MainViewModel und eine PersonViewModel und eine CompanyViewModel, von denen jede ihre eigene verwandte Ansicht hat und eine abstract Basisklasse BaseViewModel.

In BaseViewModel können wir allgemeine Eigenschaften und/oder ICommand - Instanzen hinzufügen und die Schnittstelle INotifyPropertyChanged implementieren. Da alle die Klasse BaseViewModel erweitern, können wir diese Eigenschaft in der Klasse MainViewModel haben, die auf eines unserer Ansichtsmodelle festgelegt werden kann:

public BaseViewModel ViewModel { get; set; }

Natürlich würden Sie die INotifyPropertyChanged - Schnittstelle in Ihren - Eigenschaften anders als in diesem kurzen Beispiel korrekt implementieren. Jetzt in App.xaml, wir deklarieren einige einfache DataTemplate, um die Ansichten mit den Ansichtsmodellen 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>

Wo immer wir nun eine unserer Instanzen BaseViewModel in unserer Anwendung verwenden, weisen diese DataTemplate das Framework an, stattdessen die zugehörige Ansicht anzuzeigen. Wir können sie so anzeigen:

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

Alles, was wir jetzt tun müssen, um zu einer neuen Ansicht zu wechseln, ist das Setzen der Eigenschaft ViewModel aus der Klasse MainViewModel:

ViewModel = new PersonViewModel();

Wie ändern wir die Ansichten von anderen Ansichten? Es gibt verschiedene Möglichkeiten, dies zu tun. Am einfachsten ist es jedoch, eine Binding aus der untergeordneten Ansicht direkt zu einer ICommand in der MainViewModel hinzuzufügen. Ich verwende eine benutzerdefinierte Version von RelayComand, aber Sie können jeden beliebigen Typ verwenden und ich vermute, dass Sie das Bild erhalten:

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.

109
Sheridan

Als ich mit MVVM anfing, hatte ich auch Probleme mit den verschiedenen MVVM-Frameworks und insbesondere mit dem Navigationsteil. Deshalb benutze ich dieses kleine Tutorial, das Rachel Lim erstellt hat. Es ist sehr schön und gut erklärt.

Schauen Sie es sich unter folgendem Link an:

Hoffe es hat dir geholfen :)

7
mskydt86

Vielleicht hilft Ihnen dieser Link. Setzen Sie einfach die Eigenschaft NavigateTo auf die Ansicht, die Sie im Fenster anzeigen möchten.

Als Beispiel kann man so etwas machen

<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 wäre die Klassendatei

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

        public ContentControl ViewContainer { get { return _viewContainer; } }

    }

Dann können Sie jede Ansicht als UserControl definieren und dann über den oben angegebenen Link die Schaltfläche meffed:NavigationExtensions.NavigateTo="secondView" Binden. Um das ContentControl des Window auszurichten, verwenden Sie einfach eine RelativeSource Bindung. Für z.B.

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

Stellen Sie in jeder Ansicht nur fest, dass Sie den Code hinter der Klassendefinition mit der Funktion [NavigationView("firstview")] usw. kommentieren.

Es ist zum ersten Mal kompliziert, aber es wird sehr einfach sein, sobald Sie die Idee verstanden haben.

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