[UWP]Take the control of your title bar

With Windows 10, we (as developers) have the opportunity to create both desktop and mobile apps using Universal Windows Platform.

Feel free to reach me on Twitter to discuss about this article: @deltakosh

With this in mind, I created UrzaGatherer 3.0 that you can grab freely on the store.

Today I would like to zoom on a great feature offered by UWP: the control over the title bar.

Let’s have a look on a more specific part of the previous screenshot:

As you can see, I was able to add a search box INSIDE the title bar. The interesting point here is that I actually integrated my search box into the “official” Windows shell title bar. Previously we were forced to completely replace the title bar and provide a “clone” in order to achieve the same goal (when it was possible depending on the technology used).

But stop talking now, let’s see how it works.

XAML part

The XAML side of the house is pretty simple:

<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Background="White" Grid.Row="0" x:Name="TitleBar">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid Background="{StaticResource Accent}" x:Name="BackButtonGrid">
        <Button x:Name="BackButton" Style="{StaticResource IconButtonStyle}" />
    </Grid>
    <Grid Grid.Column="1" x:Name="MainTitleBar" Background="Transparent">
        <TextBlock Text="UrzaGatherer" VerticalAlignment="Center" 
FontSize="12" FontFamily="Segoe UI" FontWeight="Normal" Margin="10,0"></TextBlock> </Grid> <TextBox Grid.Column="2" x:Name="SearchBox" x:Uid="SearchBox"></TextBox> <Grid Grid.Column="3" x:Name="RightMask"/> </Grid>

So we have a TitleBar container which contains:

  • My custom back button (I wanted to replace the original one because I was not able to control the background color which is forced to Windows Accent color and I wanted to use my lovely purple)
  • The MainTitleBar part which will be used by Windows to allow the user to grab and move your application.
  • My search box
  • A RightMask control which will be cover by windows’ controls (Minimize, Maximize and Close)

 

Please note that MainTitleBar cannot contains interactive items as all inputs will be redirected to Windows

The C# part

From the C# point of view, we have to call a couple of simple APIs:

CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.ExtendViewIntoTitleBar = true;

TitleBar.Height = coreTitleBar.Height;
Window.Current.SetTitleBar(MainTitleBar);

The idea is to get the current title bar and then ask for extending your view into the title bar.

Height is defined using the current title bar’s height.

Window.Current.SetTitleBar is used to identify which control will handle user inputs (Grab and move)

Being a great Windows citizen

As the new title bar owner, you also have some little responsibilities.

First of all you have to keep your house clean, which means that you have to clearly indicate to your user that your window is or is not the main window. To do so, I suggest mimicking what Windows is doing with just this small piece of code:

Window.Current.Activated += Current_Activated;
private void Current_Activated(object sender, WindowActivatedEventArgs e)
{
    if (e.WindowActivationState != CoreWindowActivationState.Deactivated)
    {
        BackButtonGrid.Visibility = Visibility.Visible;
        MainTitleBar.Opacity = 1;
        SearchBox.Opacity = 1;
    }
    else
    {
        BackButtonGrid.Visibility = Visibility.Collapsed;
        MainTitleBar.Opacity = 0.5;
        SearchBox.Opacity = 0.5;
    }
}

So when my window is the main window, I have this rendering:

And when it is not the main window, we switch to this one:

You also have to react to Continuum properly, which means that you are supposed to hide your title when user switch to Tablet mode. But no worry, this task is easy as well:

coreTitleBar.IsVisibleChanged += CoreTitleBar_IsVisibleChanged;
void CoreTitleBar_IsVisibleChanged(CoreApplicationViewTitleBar titleBar, object args)
{
    TitleBar.Visibility = titleBar.IsVisible ? Visibility.Visible : Visibility.Collapsed;
}

And finally you may want to respond to layout metrics changes (like scale change, etc.):

coreTitleBar.LayoutMetricsChanged += CoreTitleBar_LayoutMetricsChanged;
private void CoreTitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
{
    TitleBar.Height = sender.Height;
    RightMask.Width = sender.SystemOverlayRightInset;
}

And that’s it! You’re now ready to integrate your own UI into the title bar like Edge for instance: