master
cs 119 lines 3.13 KB
Raw
1 // Copyright (C) Microsoft Corporation. All rights reserved.
2
3 using Microsoft.UI.Xaml.Controls;
4 using Microsoft.UI.Xaml.Navigation;
5 using System.Diagnostics.CodeAnalysis;
6 using WslSettings.Contracts.Services;
7 using WslSettings.Contracts.ViewModels;
8
9 namespace WslSettings.Services;
10
11 // For more information on navigation between pages see
12 // https://github.com/microsoft/TemplateStudio/blob/main/docs/WinUI/navigation.md
13 public class NavigationService : INavigationService
14 {
15 private readonly IPageService _pageService;
16 private object? _lastParameterUsed;
17 private Frame? _frame;
18
19 public event NavigatedEventHandler? Navigated;
20
21 public Frame? Frame
22 {
23 get
24 {
25 return _frame;
26 }
27
28 set
29 {
30 UnregisterFrameEvents();
31 _frame = value;
32 RegisterFrameEvents();
33 }
34 }
35
36 [MemberNotNullWhen(true, nameof(Frame), nameof(_frame))]
37 public bool CanGoBack => Frame != null && Frame.CanGoBack;
38
39 public NavigationService(IPageService pageService)
40 {
41 _pageService = pageService;
42 }
43
44 private void RegisterFrameEvents()
45 {
46 if (_frame != null)
47 {
48 _frame.Navigated += OnNavigated;
49 }
50 }
51
52 private void UnregisterFrameEvents()
53 {
54 if (_frame != null)
55 {
56 _frame.Navigated -= OnNavigated;
57 }
58 }
59
60 public bool GoBack()
61 {
62 if (CanGoBack)
63 {
64 var vmBeforeNavigation = _frame.GetPageViewModel();
65 _frame.GoBack();
66 if (vmBeforeNavigation is INavigationAware navigationAware)
67 {
68 navigationAware.OnNavigatedFrom();
69 }
70
71 return true;
72 }
73
74 return false;
75 }
76
77 public bool NavigateTo(string pageKey, object? parameter = null, bool clearNavigation = false)
78 {
79 var pageType = _pageService.GetPageType(pageKey);
80
81 if (_frame != null && (_frame.Content?.GetType() != pageType || (parameter != null && !parameter.Equals(_lastParameterUsed))))
82 {
83 _frame.Tag = clearNavigation;
84 var vmBeforeNavigation = _frame.GetPageViewModel();
85 var navigated = _frame.Navigate(pageType, parameter);
86 if (navigated)
87 {
88 _lastParameterUsed = parameter;
89 if (vmBeforeNavigation is INavigationAware navigationAware)
90 {
91 navigationAware.OnNavigatedFrom();
92 }
93 }
94
95 return navigated;
96 }
97
98 return false;
99 }
100
101 private void OnNavigated(object sender, NavigationEventArgs e)
102 {
103 if (sender is Frame frame)
104 {
105 var clearNavigation = (bool)frame.Tag;
106 if (clearNavigation)
107 {
108 frame.BackStack.Clear();
109 }
110
111 if (frame.GetPageViewModel() is INavigationAware navigationAware)
112 {
113 navigationAware.OnNavigatedTo(e.Parameter);
114 }
115
116 Navigated?.Invoke(sender, e);
117 }
118 }
119 }