Overlapping title bars

Eduardo Gomez 3,611 Reputation points
2025-03-21T05:24:36.78+00:00

Thanks to @Junjie Zhu - MSFT

I was able to attach the title bar, becouse I want all my window to have the same

I created a class

 public static void ConfigureCustomTitleBar(
     Window window,
     string iconPath,
     string title) {

     Debug.WriteLine("ConfigureCustomTitleBar is called!");

     if(window is not null) {

         var titleBarViewModel = new CustomTitleBarViewModel(window);
         var customTitleBar = new CustomTitleBar(window) // Pass the window
         {
             DataContext = titleBarViewModel
         };

         titleBarViewModel.AppTitle = title;
         window.ExtendsContentIntoTitleBar = true;
         window.Title = title;

         var windowHandle = WindowNative.GetWindowHandle(window);
         var windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
         var appWindow = AppWindow.GetFromWindowId(windowId);
         appWindow.SetIcon(iconPath);
         appWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall;

         // Attach title bar dynamically
         var rootGrid = (Grid)window.Content;

         if(rootGrid is not null) {

             window.ExtendsContentIntoTitleBar = true;

             rootGrid.Children.Insert(0, customTitleBar); // Add title bar at the top

             window.SetTitleBar(customTitleBar.FindName("AppTitleBar") as FrameworkElement);
         }

and my user control


    <Grid
        x:Name="AppTitleBar"
        Height="100"
        Background="{StaticResource AccentAcrylicBackgroundFillColorBaseBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <!--  App Icon  -->
            <ColumnDefinition Width="*" />
            <!--  Title  -->
            <ColumnDefinition Width="Auto" />
            <!--  Minimize  -->
            <ColumnDefinition Width="Auto" />
            <!--  Maximize  -->
            <ColumnDefinition Width="Auto" />
            <!--  Close  -->
        </Grid.ColumnDefinitions>

        <!--  App Icon  -->
        <Image
            Width="24"
            Height="24"
            Margin="10,0"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Source="/Assets/AppIcon.ico" />

        <!--  App Title  -->

        <TextBlock
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            FontSize="16"
            FontWeight="Bold"
            Foreground="White"
            Text="{x:Bind ViewModel.AppTitle, Mode=TwoWay}" />

        <!--  Minimize Button  -->
        <Button
            Grid.Column="2"
            Width="30"
            Height="30"
            Margin="5"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Command="{x:Bind ViewModel.TitleBarActionsCommand}"
            CommandParameter="Minimize"
            Content="―">
            <Interactivity:Interaction.Behaviors>
                <beavior:HoverBehavior
                    HoverColor="{StaticResource TitleBarCaptionButtonHoverForegroundColor}"
                    NormalColor="Transparent" />
            </Interactivity:Interaction.Behaviors>
        </Button>

        <!--  Maximize Button  -->
        <Button
            Grid.Column="3"
            Width="30"
            Height="30"
            Margin="5"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Command="{x:Bind ViewModel.TitleBarActionsCommand}"
            CommandParameter="Maximize"
            Content="□">
            <Interactivity:Interaction.Behaviors>
                <beavior:HoverBehavior
                    HoverColor="{StaticResource TitleBarCaptionButtonForegroundColor}"
                    NormalColor="Transparent" />
            </Interactivity:Interaction.Behaviors>
        </Button>

        <!--  Close Button  -->
        <Button
            Grid.Column="4"
            Width="30"
            Height="30"
            Margin="5"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Command="{x:Bind ViewModel.TitleBarActionsCommand}"
            CommandParameter="Close"
            Content="X">
            <Interactivity:Interaction.Behaviors>
                <Interactions:EventTriggerBehavior EventName="Click" />
                <beavior:HoverBehavior
                    HoverColor="{StaticResource CloseButtonBackgroundPointerOver}"
                    NormalColor="Transparent" />
            </Interactivity:Interaction.Behaviors>
        </Button>
    </Grid>


I just putt 100 for debugging purposes

User's image

Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
870 questions
{count} votes

Accepted answer
  1. Junjie Zhu - MSFT 21,491 Reputation points Microsoft External Staff
    2025-03-21T07:40:59.1466667+00:00

    Hello @Eduardo Gomez ,

    The essence of a custom title bar is to cover the top bar of the window client area to the original non-client area (title bar, menu bar, or window frame), so if your new window wants to use a custom title bar, you must have multiple rows of grids, which means that each new window must use Grid.RowDefinitions.

    <Window
        x:Class="App1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="App1">
        <Grid>
            <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
         </Grid>
    </Window>
    

    Another point is that you don't need to be responsible for the maximize and minimize buttons. The following is my test code, I hope it will be helpful to you.

    UserControl

    <?xml version="1.0" encoding="utf-8"?>
    <UserControl
        x:Class="App1.CustomTitleBar"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:Interactivity="using:Microsoft.VisualBasic"
        mc:Ignorable="d">
        <Grid x:Name="AppTitleBar"
                        Height="48">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
                <ColumnDefinition x:Name="IconColumn" Width="Auto"/>
                <ColumnDefinition x:Name="TitleColumn" Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Image x:Name="TitleBarIcon" 
        Source="ms-appx:///Assets/AppIcon.ico"
        Grid.Column="1"
        Width="16" Height="16"
        Margin="8,0,4,0"/>
            <TextBlock x:Name="TitleBarTextBlock"
                    Text="App title" 
                    Style="{StaticResource CaptionTextBlockStyle}"
                    Grid.Column="2"
                    VerticalAlignment="Center">
            </TextBlock>
        </Grid>
     
    </UserControl>
    
    public sealed partial class CustomTitleBar : UserControl
    {
        public CustomTitleBar()
        {
            this.InitializeComponent();
        }
    }
    

    App.xaml.cs

     public partial class App : Application
     {
         /// <summary>
         /// Initializes the singleton application object.  This is the first line of authored code
         /// executed, and as such is the logical equivalent of main() or WinMain().
         /// </summary>
         public App()
         {
             this.InitializeComponent();
         }
         /// <summary>
         /// Invoked when the application is launched.
         /// </summary>
         /// <param name="args">Details about the launch request and process.</param>
         protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
         {
             m_window = new MainWindow();
             m_window.Activate();
             ConfigureCustomTitleBar(m_window,"Test");
         }
         private Window? m_window;
         public static void ConfigureCustomTitleBar(
                             Window window,
                             string title)
         {
             Debug.WriteLine("ConfigureCustomTitleBar is called!");
             if (window is not null)
             {
                
                 var customTitleBar = new CustomTitleBar();
             
                 window.ExtendsContentIntoTitleBar = true;
                 window.Title = title;
                 var windowHandle = WindowNative.GetWindowHandle(window);
                 var windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
                 var appWindow = AppWindow.GetFromWindowId(windowId);
                 appWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall;
                 // Attach title bar dynamically
                 var rootGrid = (Grid)window.Content;
                 if (rootGrid is not null)
                 {
                     rootGrid.Children.Insert(0, customTitleBar); // Add title bar at the top
                 }
             }
         }
     }
    

    Thank you.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.