Skip to content

Commit 662f544

Browse files
committed
Extending the titlebar control
1 parent 35c03df commit 662f544

File tree

5 files changed

+347
-113
lines changed

5 files changed

+347
-113
lines changed

CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<Compile Include="$(MSBuildThisFileDirectory)Attributes\PackageProjectUrlAttribute.cs" />
2525
<Compile Include="$(MSBuildThisFileDirectory)Behaviors\NavigateToUriAction.cs" />
2626
<Compile Include="$(MSBuildThisFileDirectory)Controls\TitleBar\TitleBar.cs" />
27+
<Compile Include="$(MSBuildThisFileDirectory)Controls\TitleBar\TitleBar.Properties.cs" />
2728
<Compile Include="$(MSBuildThisFileDirectory)Converters\SubcategoryToIconConverter.cs" />
2829
<Compile Include="$(MSBuildThisFileDirectory)DocOrSampleTemplateSelector.cs" />
2930
<Compile Include="$(MSBuildThisFileDirectory)Helpers\BackgroundHelper.cs" />
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace CommunityToolkit.App.Shared.Controls;
6+
7+
public partial class TitleBar : Control
8+
{
9+
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(ImageSource), typeof(TitleBar), new PropertyMetadata(default(ImageSource)));
10+
11+
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(TitleBar), new PropertyMetadata(default(string)));
12+
13+
public static readonly DependencyProperty SubtitleProperty = DependencyProperty.Register(nameof(Subtitle), typeof(string), typeof(TitleBar), new PropertyMetadata(default(string)));
14+
15+
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(object), typeof(TitleBar), new PropertyMetadata(null));
16+
17+
public static readonly DependencyProperty FooterProperty = DependencyProperty.Register(nameof(Footer), typeof(object), typeof(TitleBar), new PropertyMetadata(null));
18+
19+
public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register(nameof(IsBackButtonVisible), typeof(bool), typeof(TitleBar), new PropertyMetadata(false, IsBackButtonVisibleChanged));
20+
21+
public static readonly DependencyProperty IsPaneButtonVisibleProperty = DependencyProperty.Register(nameof(IsPaneButtonVisible), typeof(bool), typeof(TitleBar), new PropertyMetadata(false, IsPaneButtonVisibleChanged));
22+
23+
24+
25+
public ImageSource Icon
26+
{
27+
get => (ImageSource)GetValue(IconProperty);
28+
set => SetValue(IconProperty, value);
29+
}
30+
31+
public string Title
32+
{
33+
get => (string)GetValue(TitleProperty);
34+
set => SetValue(TitleProperty, value);
35+
}
36+
37+
public string Subtitle
38+
{
39+
get => (string)GetValue(SubtitleProperty);
40+
set => SetValue(SubtitleProperty, value);
41+
}
42+
43+
public object Content
44+
{
45+
get => (object)GetValue(ContentProperty);
46+
set => SetValue(ContentProperty, value);
47+
}
48+
49+
public object Footer
50+
{
51+
get => (object)GetValue(FooterProperty);
52+
set => SetValue(FooterProperty, value);
53+
}
54+
55+
public bool IsBackButtonVisible
56+
{
57+
get => (bool)GetValue(IsBackButtonVisibleProperty);
58+
set => SetValue(IsBackButtonVisibleProperty, value);
59+
}
60+
61+
public bool IsPaneButtonVisible
62+
{
63+
get => (bool)GetValue(IsPaneButtonVisibleProperty);
64+
set => SetValue(IsPaneButtonVisibleProperty, value);
65+
}
66+
67+
private static void IsBackButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
68+
{
69+
((TitleBar)d).Update();
70+
}
71+
private static void IsPaneButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
72+
{
73+
((TitleBar)d).Update();
74+
}
75+
}

CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,40 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
using System;
6-
using System.Collections.Generic;
7-
using System.Linq;
8-
using System.Runtime.InteropServices.WindowsRuntime;
95

10-
// A control to show a Fluent titlebar
6+
using Windows.ApplicationModel.Core;
117

128
namespace CommunityToolkit.App.Shared.Controls;
139

14-
[TemplateVisualState(Name = "Visible", GroupName = "BackButtonStates")]
15-
[TemplateVisualState(Name = "Collapsed", GroupName = "BackButtonStates")]
16-
[TemplatePart(Name = PartIconPresenter, Type = typeof(Button))]
10+
[TemplateVisualState(Name = BackButtonVisibleState, GroupName = BackButtonStates)]
11+
[TemplateVisualState(Name = BackButtonCollapsedState, GroupName = BackButtonStates)]
12+
[TemplateVisualState(Name = PaneButtonVisibleState, GroupName = PaneButtonStates)]
13+
[TemplateVisualState(Name = PaneButtonCollapsedState, GroupName = PaneButtonStates)]
14+
[TemplatePart(Name = PartBackButton, Type = typeof(Button))]
15+
[TemplatePart(Name = PartPaneButton, Type = typeof(Button))]
1716
[TemplatePart(Name = PartDragRegionPresenter, Type = typeof(Grid))]
18-
public sealed partial class TitleBar : Control
17+
public partial class TitleBar : Control
1918
{
2019
private const string PartDragRegionPresenter = "PART_DragRegion";
21-
private const string PartIconPresenter = "PART_BackButton";
22-
private Button? _backButton;
23-
private Grid? _dragRegion;
24-
private TitleBar? _titleBar;
25-
26-
public string Title
27-
{
28-
get => (string)GetValue(TitleProperty);
29-
set => SetValue(TitleProperty, value);
30-
}
31-
32-
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(TitleBar), new PropertyMetadata(default(string)));
20+
private const string PartBackButton = "PART_BackButton";
21+
private const string PartPaneButton = "PART_PaneButton";
3322

34-
public ImageSource Icon
35-
{
36-
get => (ImageSource)GetValue(IconProperty);
37-
set => SetValue(IconProperty, value);
38-
}
23+
private const string BackButtonVisibleState = "PaneButtonVisible";
24+
private const string BackButtonCollapsedState = "PaneButtonCollapsed";
25+
private const string BackButtonStates = "BackButtonStates";
3926

40-
public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(ImageSource), typeof(TitleBar), new PropertyMetadata(default(ImageSource)));
27+
private const string PaneButtonVisibleState = "PaneButtonVisible";
28+
private const string PaneButtonCollapsedState = "PaneButtonCollapsed";
29+
private const string PaneButtonStates = "PaneButtonStates";
4130

42-
public bool IsBackButtonVisible
43-
{
44-
get => (bool)GetValue(IsBackButtonVisibleProperty);
45-
set => SetValue(IsBackButtonVisibleProperty, value);
46-
}
4731

48-
public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register("IsBackButtonVisible", typeof(bool), typeof(TitleBar), new PropertyMetadata(default(bool), IsBackButtonVisibleChanged));
32+
private Grid? _dragRegion;
33+
private TitleBar? _titleBar;
34+
35+
4936

5037
public event EventHandler<RoutedEventArgs>? BackButtonClick;
51-
38+
public event EventHandler<RoutedEventArgs>? PaneButtonClick;
5239

5340
public TitleBar()
5441
{
@@ -59,32 +46,52 @@ protected override void OnApplyTemplate()
5946
{
6047
Update();
6148
_titleBar = (TitleBar)this;
62-
_backButton = (Button)_titleBar.GetTemplateChild(PartIconPresenter);
49+
50+
if ((Button)_titleBar.GetTemplateChild(PartBackButton) is Button backButton)
51+
{
52+
backButton.Click -= BackButton_Click;
53+
backButton.Click += BackButton_Click;
54+
}
55+
56+
if ((Button)_titleBar.GetTemplateChild(PartPaneButton) is Button paneButton)
57+
{
58+
paneButton.Click -= PaneButton_Click;
59+
paneButton.Click += PaneButton_Click;
60+
}
6361
_dragRegion = (Grid)_titleBar.GetTemplateChild(PartDragRegionPresenter);
64-
_backButton.Click += _backButton_Click;
62+
63+
6564

6665
SetTitleBar();
6766
base.OnApplyTemplate();
6867
}
6968

70-
private void _backButton_Click(object sender, RoutedEventArgs e)
69+
private void BackButton_Click(object sender, RoutedEventArgs e)
7170
{
7271
OnBackButtonClicked();
7372
}
7473

74+
private void PaneButton_Click(object sender, RoutedEventArgs e)
75+
{
76+
OnPaneButtonClicked();
77+
}
78+
7579
private void OnBackButtonClicked()
7680
{
7781
BackButtonClick?.Invoke(this, new RoutedEventArgs());
7882
}
7983

80-
private static void IsBackButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
84+
private void OnPaneButtonClicked()
8185
{
82-
((TitleBar)d).Update();
86+
PaneButtonClick?.Invoke(this, new RoutedEventArgs());
8387
}
8488

89+
90+
8591
private void Update()
8692
{
87-
VisualStateManager.GoToState(this, IsBackButtonVisible ? "Visible" : "Collapsed", true);
93+
VisualStateManager.GoToState(this, IsBackButtonVisible ? BackButtonVisibleState : BackButtonCollapsedState, true);
94+
VisualStateManager.GoToState(this, IsPaneButtonVisible ? PaneButtonVisibleState : PaneButtonCollapsedState, true);
8895
}
8996

9097
private void SetTitleBar()
@@ -97,8 +104,20 @@ private void SetTitleBar()
97104
#endif
98105
#if WINDOWS_UWP && !HAS_UNO
99106
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
107+
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += this.TitleBar_LayoutMetricsChanged;
100108
Window.Current.SetTitleBar(_dragRegion);
101109
// NOT SUPPORTED IN UNO WASM
102110
#endif
103111
}
112+
113+
private void TitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
114+
{
115+
if (_titleBar != null)
116+
{
117+
ColumnDefinition Left = (ColumnDefinition)_titleBar.GetTemplateChild("LeftPaddingColumn");
118+
ColumnDefinition Right = (ColumnDefinition)_titleBar.GetTemplateChild("RightPaddingColumn");
119+
Left.Width = new GridLength(CoreApplication.GetCurrentView().TitleBar.SystemOverlayLeftInset);
120+
Right.Width = new GridLength(CoreApplication.GetCurrentView().TitleBar.SystemOverlayRightInset);
121+
}
122+
}
104123
}

0 commit comments

Comments
 (0)