FrameNavigationService - toligmueller/WPF-MVVM-App-.NET5.0 GitHub Wiki

Vorausgesetzte Lektüre

Der FrameNavigationService ist ein Service der die Steuerung einer (WPF)ContentControl übernimmt.

<ContentControl Frame="{Binding FrameNavigationService.Frame}"/>

In der ContentControl können wir innerhalb einer View Pages anzeigen lassen.

ViewModels die eine Navigation implementieren folgen nicht mehr das MVVM Entwicklungsmuster, da es direkte Verweise zu den Views besteht, aber dies in diesem Fall unumgänglich.

Konstruktor

Hier haben wir die Möglichkeit eine Uri anzugeben die standardmäßig angezeigt werden kann.

Properties
  • Frame: Hier wird der Content ausgegeben.
  • CanGoBack & CanGoForward: Geben einen bool Wert zurück ob man im Frame rückwärts oder vorwärts Navigieren kann, Stichwort "History".
Methoden
  • CanNavigateTo(Uri) Gibt ein bool Wert zurück ob man zu der gewünschten Page navigieren kann oder man sich schon auf dieser befindet.
  • Navigate(Uri) /Navigate(Type)/Navigate(object): Stellt die gewünschte Page im Frame dar.
  • GoBack()/GoForward(): Navigiert rückwärts bzw. vorwärts.

Beispiel Code

MainWindowView.xaml

Hier haben wir eine ContentControl für die Anzeige der Pages und ein Button um zu navigieren.

<Window x:Class="Beispiel.Views.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindowView" 
        Height="450"
        Width="800"
        DataContext="{Binding MainWindowVM, Source={StaticResource Locator}}">
    <Grid>
        <Button Width="100" 
                Heigth="30" 
                HorizontalAlligment="Left" 
                Content="Über uns" Command={Binding GoToAboutUsCmd}/>
        <ContentControl Width="700" 
                        HorizontalAlligment="Right" 
                        Content="{Binding FrameNavigationService.Frame}"/>
    </Grid>
</Window>
MainWindowViewModel.cs

Im ViewModel haben wir die Anhängigkeit zum Navigations Service im Konstruktor definiert und der RelayCommand sagt diesem welche Page er anzeigen soll.

using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input.Wpf;
using Beispiel.Services;

namespace Beispiel.ViewModels
{
    public class MainWindowViewModel : ObservableObject
    {
        public IFrameNavigationService FrameNavigationService { get; }

        public MainWindowViewModel(IFrameNavigationService frameNavigationService)
        {
            FrameNavigationService = frameNavigationService;
        }

        public RelayCommand GoToAboutUsCmd => new(
            () =>
            {
		FrameNavigationService.Navigate(new Uri("Views/AboutUsPageView.xaml", UriKind.RelativeOrAbsolute));
            },
            () => FrameNavigationService.CanNavigateTo(new Uri("Views/AboutUsPageView.xaml", UriKind.RelativeOrAbsolute);
        );
    }
}
AboutUsPageView.xaml
<Page x:Class="Beispiel.Views.AboutUsPageView"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Height="450"
        Width="800"
        DataContext="{Binding AboutUsPageVM, Source={StaticResource Locator}}">
    <Grid>
	<Label Content="Wir sind echt cool!"/>
    </Grid>
</Page>
ViewModelLocator.cs

Damit der Service im ViewModel verfügbar ist, muss dieser vorher im ViewModelLocator angegeben werden.

using System;
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Beispiel.Services;

namespace Beispiel.ViewModels
{
    public class ViewModelLocator
    {
        public IServiceProvider Services { get; }

        public MainWindowViewModel MainWindowVM => Services.GetService<MainWindowViewModel>();
        public AboutUsPageViewModel AboutUsPageVM => Services.GetService<AboutUsPageViewModel>();

        public ViewModelLocator()
        {
            Services = GetServices();
        }

        private static IServiceProvider GetServices()
        {
            IServiceCollection serviceCollection = new ServiceCollection();

             serviceCollection.AddSingleton<IFrameNavigationService>(new FrameNavigationService(new Uri("Views/MainWindowView.xaml", UriKind.RelativeOrAbsolute)));
            
            serviceCollection.AddSingleton<BeispielAViewModel>();
            serviceCollection.AddSingleton<BeispielAViewModel>();

            return serviceCollection.BuildServiceProvider();
        }
    }
}
⚠️ **GitHub.com Fallback** ⚠️