2017-12-16 2 views
0

Ich habe eine WPF-Anwendung, die ein Fenster enthält. Nur dieses Fenster werfen der Benutzer kann seine Navigation in der App durchführen.WPF MVVM: MainWindow Navigation

der Anwendungsstruktur ist:

  • MainWindow.xaml
  • MainWindowViewModel.cs
  • StartPage.xaml
  • StartPageViewMode.cs
  • Systems.xaml
  • Systems.cs
  • Andere Ansichten und ähnliche Modelle.

MainWindow.xaml

<Grid> 
    <ContentControl Content="{Binding CurrentWorkspace}" x:Name="ContentControlMainWindow" VerticalAlignment="Stretch"/> 
</Grid> 

MainWindowViewModel.cs

private ContentControl _currentWorkspace; 
public ContentControl CurrentWorkspace 
{ 
    get => _currentWorkspace; 
    set => SetProperty(ref _currentWorkspace, value); 
} 

//c'tor 
public MainWindowViewModel() 
{ 
    CurrentWorkspace.Content = new ContentControl { Content = new StartPage() 
} 

Wie Sie bei der Initialisierung der Anwendung sehen kann ich auf die CurrentWorkspace der Startseite Ansicht bin Laden. Jetzt vom StartPageViewModel muss ich den CurrentWorkspace Inhalt zu einer anderen Ansicht ändern. Grundsätzlich habe ich Mühe, diesen CurrentWorkspace von jedem Teil der Anwendung zu kontrollieren (und zu ändern).

+0

Siehe Navigationskonzepte in WPF. – Aybe

Antwort

0

Ich mag diese Art von Ansatz:

In MainWindowViewModel.cs:

// You would more likely type this as something like ViewModelBase/ObservableObject/etc. 
private object _currentWorkspace; 
public object CurrentWorkspace 
{ 
    get => _currentWorkspace; 
    set => SetProperty(ref _currentWorkspace, value); 
} 

private StartPageViewModel _startPageViewModel; 
public StartPageViewModel StartPageViewModel 
{ 
    get => _startPageViewModel; 
    set => SetProperty(ref _startPageViewModel, value); 
} 

private AnotherPageViewModel _anotherPageViewModel; 
public AnotherPageViewModel AnotherPageViewModel 
{ 
    get => _anotherPageViewModel; 
    set => SetProperty(ref _anotherPageViewModel, value); 
} 

public MainWindowViewModel() 
{ 
    StartPageViewModel = new StartPageViewModel(); 
    AnotherPageViewModel = new AnotherPageViewModel(); 

    CurrentWorkspace = StartPageViewModel; 
} 

// Navigation Method 
private void NavigateToStartPage() 
{ 
    if (CurrentWorkspace != StartPageViewModel) 
     CurrentWorkspace = StartPageViewModel; 
} 

// Navigation Method 
private void NavigateToAnotherPage() 
{ 
    if (CurrentWorkspace != AnotherPageViewModel) 
     CurrentWorkspace = AnotherPageViewModel; 
} 

In MainWindow.xaml:

<Window ... 
    xmlns:vm="clr-namespace:App.ViewModels" 
    xmlns:vw="clr-namespace:App.Views" 
    ... > 
    <Window.DataContext> 
     <vm:MainWindowViewModel /> 
    </Window.DataContext> 
    <Grid> 
     <ContentControl x:Name="ContentControlMainWindow" 
         Content="{Binding CurrentWorkspace}" 
         VerticalAlignment="Stretch"> 
      <ContentControl.Resources> 
       <DataTemplate x:Key="start_page_view" 
           DataType="{x:Type vm:StartPageViewModel}"> 
        <vw:StartPage /> 
       </DataTemplate> 
       <DataTemplate x:Key="another_page_view" 
           DataType="{x:Type vm:AnotherPageViewModel}"> 
        <vw:AnotherPage /> 
       </DataTemplate> 
      </ContentControl.Resources> 
     </ContentControl> 
    </Grid> 
</Window/> 

Sie dann CurrentWorkspace festlegen können, was auch immer Sie wollen. Wenn Sie beispielsweise die Instanz StartPageViewModel entsorgen möchten, können Sie einfach StartPageViewModel = null; setzen.

Es wird allgemein als eine Verletzung von MVVM angesehen, UI-Elemente, z. B. ContentControl, in Ihren ViewModels zu haben.

+0

Dank Chris, ich verstehe immer noch nicht, wie kann ich den aktuellen Arbeitsbereich von anderen Ansichtsmodell (wer ist nicht das Hauptfenster Ansichtsmodell)? – gr1d3r

+0

Ich habe eine andere Eigenschaft sowie zwei Navigationsmethoden hinzugefügt, die dies hoffentlich erklären werden - es ist dann eine Frage des Aufrufs dieser Methoden auf 'MainWindowViewModel', typischerweise über eine Art von' ICommand'. Lass es mich wissen, wenn dies das erklärt. –