Search code examples
c#wpfwindow-chrome

Adding buttons to the Window Bar, while using Window Chrome


I am developing an application using a WPF in VSCode 2022. In order to make a custom Window Bar and simultaniously keep the normal window functions (i.e. Dragging the window around), I decided to use the WindowChrome Class.

But now i am facing the problem, that the buttons on the top are not responding anymore, because the top of the window now has the funtion of dragging the window around.

I want to find a workaround, that lets me have to default window functions and lets me customize the window bar.

xaml:

<Window x:Class="ConsoleWindow_v0._0._1.MainWindow"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ConsoleWindow_v0._0._1"
        mc:Ignorable="d"
        WindowStyle="None"
        Height="450" Width="800">

    <Window.Resources>
       ...
    </Window.Resources>


    <Grid x:Name="ParentGrid"
          Margin="0, 0, 0, 0"
          Background="#191919">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="1"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>

        <!--Window Handle-->
        <Grid x:Name="ChildGrid_1"
              Grid.Row="0"
              Margin="3,3,3,0"
              VerticalAlignment="Stretch"
              HorizontalAlignment="Stretch">

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <!--System Buttons-->
            <Grid x:Name="SystemButtons"
                        Grid.Column="1"
                        Background="#1f1f1f"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Right">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <Button x:Name="MinimizeButton"
                        Grid.Column="0"
                        HorizontalAlignment="Stretch"
                        KeyboardNavigation.IsTabStop="False"
                        Click="MinimizeButton_Click"
                        Content="-"
                        Style="{StaticResource SystemButtonStyle}"/>

                <Button x:Name="MaximizeButton"
                        Grid.Column="1"
                        HorizontalAlignment="Stretch"
                        KeyboardNavigation.IsTabStop="False"
                        Click="MaximizeButton_Click"
                        Content="□"
                        Style="{DynamicResource SystemButtonStyle}" />

                <Button x:Name="CloseButton"
                        Grid.Column="2"
                        HorizontalAlignment="Stretch"
                        KeyboardNavigation.IsTabStop="False"
                        Content="x"
                        Click="CloseButton_Click"
                        Style="{DynamicResource SystemButtonStyle}"/>

            </Grid>

            <!--Window Title-->
            <StackPanel x:Name="HandleBar"
                  Background="#1f1f1f"
                  Grid.Column="0"
                  Orientation="Horizontal">

                <Grid x:Name="g"
                      Grid.Column="0"
                      Grid.Row="0"
                      Width="{StaticResource WindowHandle_Height}"
                      Height="{StaticResource WindowHandle_Height}"
                      HorizontalAlignment="Left"
                      VerticalAlignment="Center">

                    <Image x:Name="Icon" 
                           HorizontalAlignment="Stretch"
                           VerticalAlignment="Stretch"                           
                           Width="Auto"
                           Height="Auto"
                           Opacity="0.65"
                           Source="/Zeichnung.png"/>
                </Grid>

                <Button x:Name="DateiButton"
                        Grid.Column="1"
                        Grid.Row="0"
                        Style="{StaticResource UserButtons}"
                        Content="Datei"/>

                <Button x:Name="SettingsButton"
                        Grid.Column="1"
                        Grid.Row="0"
                        Style="{StaticResource UserButtons}"
                        Content="Settings"/>

                <Button x:Name="AnsichtButton"
                        Grid.Column="2"
                        Grid.Row="0"
                        Style="{StaticResource UserButtons}"
                        Content="Ansicht"/>

            </StackPanel>

            <!--Window Handle-->

        </Grid>

        <!--Client Area-->
        <Grid x:Name="ChildGrid_2"
              Grid.Row="1">
            ...

            </Grid>
        </Grid>

        <!--Quick Settings-->
        <Grid x:Name="QuickSettingsGrid"
              Grid.Row="3"
              Margin="3,3,3,3">
                ...
        </Grid>


    </Grid>

</Window>

Code Behind:

public MainWindow() {
            InitializeComponent();
            WindowChrome.SetWindowChrome(this, new WindowChrome());
            WindowChrome.IsHitTestVisibleInChromeProperty = true;

            ChildGrid_1.ColumnDefinitions[1].Width = new GridLength(3 * systemButton_size);
        }

I have already tried implementing the default window functions myself, but i couldn't all features to work.

Sulotion For anyone who has the same issue and is working with Window Chrome from the Code Behind, here is how i fixed it (Based on the answer of @emoacht):

InitializeComponent();
foreach (UIElement element in SystemButtons.Children) {
    WindowChrome.SetIsHitTestVisibleInChrome(element, true);
}
foreach (UIElement element in HandleBar.Children) {
    WindowChrome.SetIsHitTestVisibleInChrome(element, true);
}

Solution

  • You misunderstand the usage of WindowChrome.IsHitTestVisibleInChrome attached property. It should be set in each control which is covered by CaptionHeight but need to be hit test visible.

    In your case, you can insert the following to SystemButtonStyle.

    <Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>