[UWP] Occupation Title Bar

Original text: [UWP]Occupy the title bar

1. Preface#< /h2>

Every ideal UWP application will have the idea of ​​a title bar, especially when Microsoft provides the function of extending Acrylic to the title bar, most of the native Windows 10 applications are not behaved and have occupied the title. One acre of land in the fence. This blog will introduce how to customize the title bar in UWP.

2. Sample code#

UWP has many restrictions, the title bar Almost all content of the customization is in this document. But just referring to this article is not easy enough. I wrote a sample application by referring to TitleBar in Microsoft’s open source calculator application. You can view its source code here. I also applied TitleBar to my OnePomodoro application.

3. Simple color customization#

If you just want simple The color of the title bar can be customized locally through ApplicationViewTitleBar. ApplicationViewTitleBar represents the title bar of the application. It provides some color attributes to control the color of the title bar. The sample code is as follows:

 < div class="esa-clipboard-button" data-clipboard-target="#copy_target_0" title="copy code"> Copy 
// using Windows.UI.ViewManagement ; var titleBar = ApplicationView.GetForCurrentView().TitleBar; // Set active window colors titleBar.ForegroundColor = Windows.UI.Colors.White; titleBar.BackgroundColor = Windows.UI.Colors.Green; titleBar.ButtonForegroundColor = Windows.UI.Colors.White; titleBar.ButtonBackgroundColor = Windows.UI.Colors.SeaGreen; titleBar.ButtonHoverForegroundColor = Windows.UI.Colors.White; titleBar.ButtonHoverBackgroundColor = Windows.UI.Colors.DarkSeaGreen; titleBar.ButtonPressedForegroundColor = Windows.UI.Colors.Gray; titleBar.ButtonPressedBackgroundColor = Windows.UI.Colors.LightGreen; // Set inactive window colors titleBar.InactiveForegroundColor = Windows.UI.Colors.Gray; titleBar.InactiveBackgroundColor = Windows.UI.Colors.SeaGreen; titleBar.ButtonInactiveForegroundColor = Windows.UI.Colors.Gray; titleBar.ButtonInactiveBackgroundColor = Windows.UI.Colors.SeaGreen;

There are a few points to note:

  • Background definitions for hovering and pressing are invalid for the close button li>
  • Foreground can’t set transparency

4. Expand the content to the title bar span>#

To hide the default title bar and extend your content to the title bar area, set the CoreApplicationViewTitleBar.ExtendViewIntoTitleBar property to true. CoreApplicationViewTitleBar allows applications to define a custom title bar displayed in the application window. The sample code is as follows:

 
Copy
< span class="hljs-comment">// using Windows.ApplicationModel.Core; // Hide default title bar. var coreTitleBar = CoreApplication.GetCurrentView().TitleBar; coreTitleBar.ExtendViewIntoTitleBar = true;

5. Extend the content to the title Customize the color of the title button when creating a column#

Extending the content to the title bar, the color of the title button becomes more complicated. Because the color of the application content may conflict with the color of the button. In this case, there are several solutions, the simplest of which is to write a color that does not conflict, but it may cause problems with these colors when switching themes. The calculator app subscribes to the ColorValuesChanged event of UISettings, dynamically changes the color of the title bar according to the value of ThemeResources, and further considers the use of high-contrast themes, so it subscribes to the HighContrastChanged event of AccessibilitySettings:

 
Copy
if (_accessibilitySettings.HighContrast) { // Reset to use default colors. applicationTitleBar.ButtonBackgroundColor = null; applicationTitleBar.ButtonForegroundColor = null; applicationTitleBar.ButtonInactiveBackgroundColor = null; applicationTitleBar.ButtonInactiveForegroundColor = null; applicationTitleBar.ButtonHoverBackgroundColor = null; applicationTitleBar.ButtonHoverForegroundColor = null; applicationTitleBar.ButtonPressedBackgroundColor = null; applicationTitleBar.ButtonPressedForegroundColor = null; } else { Color bgColor = Colors.Transparent; Color fgColor = ((SolidColorBrush)Application.Current.Resources["SystemControlPageTextBaseHighBrush"]).Color; Color inactivefgColor = ((SolidColorBrush)Application.Current.Resources["SystemControlForegroundChromeDisabledLowBrush"]).Color; Color hoverbgColor = ((SolidColorBrush)Application.Current.Resources["SystemControlBackgroundListLowBrush"]).Color; Color hoverfgColor = ((SolidColorBrush)Application.Current.Resources["SystemControlForegroundBaseHighBrush"]).Color; Color pressedbgColor = ((SolidColorBrush)Application.Current.Resources["SystemControlBackgroundListMediumBrush"]).Color; Color pressedfgColor = ((SolidColorBrush)Application.Current.Resources["SystemControlForegroundBaseHighBrush"]).Color; applicationTitleBar.ButtonBackgroundColor = bgColor; applicationTitleBar.ButtonForegroundColor = fgColor; applicationTitleBar.ButtonInactiveBackgroundColor = bgColor; applicationTitleBar.ButtonInactiveForegroundColor = inactivefgColor; applicationTitleBar.ButtonHoverBackgroundColor = hoverbgColor; applicationTitleBar.ButtonHoverForegroundColor = hoverfgColor; applicationTitleBar.ButtonPressedBackgroundColor = pressedbgColor; applicationTitleBar.ButtonPressedForegroundColor = pressedfgColor; }

In this code, when using a high-contrast theme, the button color of the title bar is restored to the default value, otherwise it is set to the corresponding color in the ThemeResource, the operation effect is as follows:

Share pictures

But now UWP applications often repeat between Dark and Light themes Horizontal jump, and Application.Current.Resources can only get the value of ThemeResource when the program is loaded, so this code is invalid after the theme is switched in the application. I don’t know how to get the latest ThemeResource in the code. To solve this problem, I have to let TitleBar get the current ThemeResource in XAML. The code is as follows:

 
Copy
<UserControl .Resources> <SolidColorBrush x:Key="ButtonForegroundColor" Color="{ThemeResource SystemBaseHighColor}" />< /span> <SolidColorBrush x:Key="ButtonInactiveForegroundBrush" Color="{ThemeResource SystemChromeDisabledLowColor}" />< /span> <SolidColorBrush x:Key="ButtonHoverBackgroundBrush" Color="{ThemeResource SystemListLowColor}" />< /span> <SolidColorBrush x:Key="ButtonHoverForegroundBrush" Color="{ThemeResource SystemBaseHighColor}" />< /span> <SolidColorBrush x:Key="ButtonPressedBackgroundBrush" Color="{ThemeResource SystemListMediumColor}" />< /span> <SolidColorBrush x:Key="ButtonPressedForegroundBrush" Color="{ThemeResource SystemBaseHighColor}" />< /span> UserControl.Resources>
 
Copy
Color fgColor = ((SolidColorBrush)Resources["ButtonForegroundColor "]).Color; Color inactivefgColor = ((SolidColorBrush)Resources["ButtonInactiveForegroundBrush"]).Color; Color hoverbgColor = ((SolidColorBrush)Resources["ButtonHoverBackgroundBrush"]).Color; Color hoverfgColor = ((SolidColorBrush)Resources["ButtonHoverForegroundBrush"]).Color; Color pressedbgColor = ((SolidColorBrush)Resources["ButtonPressedBackgroundBrush"]).Color; Color pressedfgColor = ((SolidColorBrush)Resources["ButtonPressedForegroundBrush"]).Color;

share picture

6. Draggable area #

I have expanded the content to the title bar. I definitely want to place the UI elements I need on the title bar. By default, the scope of the title bar is drag, click, etc. Windows The behavior of the form is preserved, and the custom UI content in this range cannot get mouse clicks. In order to let the custom UI content get the mouse, you can use the Window.SetTitleBar method to specify that an element can be used for dragging and clicking on the form.

 
Copy
<Grid x:Name=" LayoutRoot" Height="32" HorizontalAlignment ="Stretch"> <Grid x:Name="BackgroundElement" Height="32" Background="Transparent" /> <StackPanel Orientation="Horizontal"> <StackPanel x:Name="ItemsPanel" Orientation="Horizontal"> StackPanel> <TextBlock x:Name="AppName" x:Uid="AppName" Text="ExtendViewIntoTitleBarDemo" StackPanel> Grid>
 
Copy
Window.Current.SetTitleBar(BackgroundElement);

The above code specifies the The BackgroundElement element is a draggable area, and the StackPanel below is used to place interactive content, such as a title or a back button. This StackPanel must have a higher Z order than BackgroundElement in order to receive user mouse input.

7. System reserved area of ​​the title#

The right side of the title bar There is a system reserved area of ​​188 pixels for system title buttons (“Back”, “Minimize”, “Maximize”, “Close”). In fact, these buttons take up a 141-pixel control, and there is a small space that is the default draggable area. This small space ensures that no matter how you set it, there is always an area where the user can drag.

share picture

The 188 pixels mentioned above are 100 %The zooming situation, as you can see from the screenshot above, may actually be different, usually when the form is loaded, or subscribe to the CoreApplicationViewTitleBar.LayoutMetricsChanged event, and then get the specific value through CoreApplicationViewTitleBar.

 
Copy
_coreTitleBar.LayoutMetricsChanged += OnLayoutMetricsChanged; private void OnLayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args) { LayoutRoot.Height = _coreTitleBar.Height; SetTitleBarPadding(); } private void SetTitleBarPadding() { double leftAddition = 0; double rightAddition = 0; if (FlowDirection == FlowDirection.LeftToRight) { leftAddition = _coreTitleBar.SystemOverlayLeftInset; rightAddition = _coreTitleBar.SystemOverlayRightInset; } else { leftAddition = _coreTitleBar.SystemOverlayRightInset; rightAddition = _coreTitleBar.SystemOverlayLeftInset; } LayoutRoot.Padding = new Thickness(leftAddition, 0, rightAddition, 0); }

8. The content of the interactive area#

The above< code>StackPanel is the interactive area. The detailed content is as follows:

 
Copy
<StackPanel Orientation< /span>="Horizontal"> <StackPanel x:Name="ItemsPanel" Orientation="Horizontal"> <StackPanel.Resources> <Style TargetType="Button" BasedOn="{StaticResource NavigationBackButtonNormalStyle}"> <Setter Property= "Foreground" Value="{StaticResource TitleBarForeground}"< /span> /> <Setter Property ="FontSize" Value="10" /> <Setter Property=< span class="hljs-string">"Width" Value="46 " /> <Setter Property span>="Height" Value="32"< /span> /> <Setter Property ="IsTabStop" Value="False" /> Style> StackPanel.Resources> StackPanel> <TextBlock x:Name="AppName" x:Uid="AppName" Text="ExtendViewIntoTitleBarDemo" Margin="12,0,12,0" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground= "{ThemeResource SystemControlPageTextBaseHighBrush}" FontSize="12"< /span> IsHitTestVisible="False" TextAlignment="Left" TextTri mming="CharacterEllipsis" /> StackPanel>

where AppName is used for Display the title bar, ItemsPanel is used to place other buttons. The Buttons attribute is defined in TitleBar, and the button can be specified by the Buttons attribute when calling TitleBar. changed).

 
Copy
public ObservableCollection
 
Copy
<local:TitleBar> <local:TitleBar.Buttons> <Button x:Name="OptionsButton" Content="" ToolTipService.ToolTip="Options" /> <Button Content="" ToolTipService.ToolTip="Options" />< /span> <Button Content="" ToolTipService.ToolTip="Options" />< /span> <Button Content="" ToolTipService.ToolTip="Options" />< /span> local:TitleBar.Buttons> local:TitleBar>

share picture

The style of the button comes from NavigationBackButtonNormalStyle and slightly modified, so that it is roughly the same as the standard The title bar button is the same.

9. Title bar color in inactive state#

When the window When the body is in the inactive state, the button and title should be grayed out. You can subscribe to the Activated event of Window, and change the color when in the inactive state:

 
Copy
Window.Current.Activated += OnWindowActivated; private void OnWindowActivated(Object sender, WindowActivatedEventArgs e) { VisualStateManager.GoToState( this, e.WindowActivationState == CoreWindowActivationState.Deactivated? WindowNotFocused.Name: WindowFocused.Name, false); }
 
Copy
<UserControl.Resources> <SolidColorBrush x:Key="TitleBarForeground" x:Name="TitleBarForeground" Color="{ThemeResource SystemBaseHighColor}" /> UserControl.Resources> <Grid x:Name="LayoutRoot" Height="32" HorizontalAlignment="Stretch"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="WindowFocusStates"> <VisualState x:Name="WindowFocused" /> <VisualState x:Name="WindowNotFocused"> <VisualState.Setters> <Setter Target="AppName.Foreground" Value="{ThemeResource SystemControlForegroundChromeDisabledLowBrush}" />< /span> <Setter Target="TitleBarForeground.Color" Value="{ThemeResource SystemChromeDisabledLowColor}" />< /span> VisualState.Setters> VisualState> VisualStateGroup> VisualStateManager.VisualStateGroups>

share picture

10. Full screen and tablet mode< /span>#

When the app is running in full screen or tablet mode, the system will hide the title bar and title control buttons. However, the user can call the title bar to display it as an overlay on top of the app’s UI. You can handle the CoreApplicationViewTitleBar.IsVisibleChanged event that will be notified when you hide or call the title bar, and show or hide the content of your custom title bar as needed.

 
Copy
LayoutRoot.Visibility = _coreTitleBar .IsVisible? Visibility.Visible: Visibility.Collapsed;

This part is more difficult to take a screenshot and I won’t do it. If you want to see the effect, you can try my Pomodoro app.

11. Conclusion#

That’s it, it’s a headache Finished defining the title bar. Fortunately, Microsoft has open sourced its calculator. There is just the code I need in the calculator, so I copied it. Some are not handled well, please correct me if you make a mistake.

12. Reference#

Title bar customization

calculator_TitleBar.xaml.cpp at master

ApplicationViewTitleBar Class (Windows.UI.ViewManagement)-Windows UWP applications Microsoft Docs

CoreApplicationViewTitleBar Class (Windows.ApplicationModel.Core)-Windows UWP applications Microsoft Docs

13. Source code#

DinoChan_ExtendViewIntoTitleBarDemo How to handle titlebar when ExtendViewIntoTitleBar

OnePomodoro_TitleBar.xaml at master

Copy

Copy

Copy

Copy

Copy

Copy

Copy

Copy

Copy

Copy< /p>

Copy

Copy

Copy

Copy

Leave a Comment

Your email address will not be published.