master
cs 124 lines 4.42 KB
Raw
1 // Copyright (C) Microsoft Corporation. All rights reserved.
2
3 using Microsoft.UI.Xaml;
4 using Microsoft.UI.Xaml.Controls;
5 using Microsoft.UI.Xaml.Navigation;
6 using Microsoft.Xaml.Interactivity;
7
8 using WslSettings.Contracts.Services;
9
10 namespace WslSettings.Behaviors;
11
12 public class NavigationViewHeaderBehavior : Behavior<NavigationView>
13 {
14 private static NavigationViewHeaderBehavior? _current;
15
16 private Page? _currentPage;
17
18 public DataTemplate? DefaultHeaderTemplate
19 {
20 get; set;
21 }
22
23 public object DefaultHeader
24 {
25 get => GetValue(DefaultHeaderProperty);
26 set => SetValue(DefaultHeaderProperty, value);
27 }
28
29 public static readonly DependencyProperty DefaultHeaderProperty =
30 DependencyProperty.Register("DefaultHeader", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current!.UpdateHeader()));
31
32 public static NavigationViewHeaderMode GetHeaderMode(Page item) => (NavigationViewHeaderMode)item.GetValue(HeaderModeProperty);
33
34 public static void SetHeaderMode(Page item, NavigationViewHeaderMode value) => item.SetValue(HeaderModeProperty, value);
35
36 public static readonly DependencyProperty HeaderModeProperty =
37 DependencyProperty.RegisterAttached("HeaderMode", typeof(bool), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(NavigationViewHeaderMode.Always, (d, e) => _current!.UpdateHeader()));
38
39 public static object GetHeaderContext(Page item) => item.GetValue(HeaderContextProperty);
40
41 public static void SetHeaderContext(Page item, object value) => item.SetValue(HeaderContextProperty, value);
42
43 public static readonly DependencyProperty HeaderContextProperty =
44 DependencyProperty.RegisterAttached("HeaderContext", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current!.UpdateHeader()));
45
46 public static DataTemplate GetHeaderTemplate(Page item) => (DataTemplate)item.GetValue(HeaderTemplateProperty);
47
48 public static void SetHeaderTemplate(Page item, DataTemplate value) => item.SetValue(HeaderTemplateProperty, value);
49
50 public static readonly DependencyProperty HeaderTemplateProperty =
51 DependencyProperty.RegisterAttached("HeaderTemplate", typeof(DataTemplate), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current!.UpdateHeaderTemplate()));
52
53 protected override void OnAttached()
54 {
55 base.OnAttached();
56
57 var navigationService = App.GetService<INavigationService>();
58 navigationService.Navigated += OnNavigated;
59
60 _current = this;
61 }
62
63 protected override void OnDetaching()
64 {
65 base.OnDetaching();
66
67 var navigationService = App.GetService<INavigationService>();
68 navigationService.Navigated -= OnNavigated;
69 }
70
71 private void OnNavigated(object sender, NavigationEventArgs e)
72 {
73 if (sender is Frame frame && frame.Content is Page page)
74 {
75 _currentPage = page;
76
77 UpdateHeader();
78 UpdateHeaderTemplate();
79 }
80 }
81
82 private void UpdateHeader()
83 {
84 if (_currentPage != null && AssociatedObject != null)
85 {
86 var headerMode = GetHeaderMode(_currentPage);
87 if (headerMode == NavigationViewHeaderMode.Never)
88 {
89 AssociatedObject.Header = null;
90 AssociatedObject.AlwaysShowHeader = false;
91 }
92 else
93 {
94 var headerFromPage = GetHeaderContext(_currentPage);
95 if (headerFromPage != null)
96 {
97 AssociatedObject.Header = headerFromPage;
98 }
99 else
100 {
101 AssociatedObject.Header = DefaultHeader;
102 }
103
104 if (headerMode == NavigationViewHeaderMode.Always)
105 {
106 AssociatedObject.AlwaysShowHeader = true;
107 }
108 else
109 {
110 AssociatedObject.AlwaysShowHeader = false;
111 }
112 }
113 }
114 }
115
116 private void UpdateHeaderTemplate()
117 {
118 if (_currentPage != null)
119 {
120 var headerTemplate = GetHeaderTemplate(_currentPage);
121 AssociatedObject.HeaderTemplate = headerTemplate ?? DefaultHeaderTemplate;
122 }
123 }
124 }