Dragging custom window title bar from top when maximized does not work

c#, customization, titlebar, window, wpf

Solution

I am able to get the desired behavior of title bar including aero snap in pure xaml

as result you can see a custom title bar, it is completely draggable, double click to maximize and restore and drag to snap and unsnap.

xaml

<Window x:Class="CSharpWPF.MainWindow" 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" >
    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="{Binding ActualHeight,ElementName=titlebar}"/>
    </WindowChrome.WindowChrome>
    <DockPanel LastChildFill="True">
        <Border Background="LightBlue" DockPanel.Dock="Top" Height="25" x:Name="titlebar">
            <TextBlock Text="{Binding Title, RelativeSource={RelativeSource FindAncestor,AncestorType=Window},FallbackValue=Title}" 
                       Margin="10,0,0,0"
                       VerticalAlignment="Center">
                <TextBlock.Effect>
                    <DropShadowEffect Color="White" ShadowDepth="3"/>
                </TextBlock.Effect>
            </TextBlock>
        </Border>
        <Border BorderBrush="LightGray" BorderThickness="1" Padding="4">
            <TextBlock Text="Window content"/>
        </Border>
    </DockPanel>
</Window>

result

so now you don't need any code behind to handle title bar manually.

Reusable styles

you can also wrap above in a custom style which you can apply on several windows

<Style TargetType="Window" x:Key="CustomTitleBar">
    <Setter Property="WindowChrome.WindowChrome">
        <Setter.Value>
            <WindowChrome CaptionHeight="{x:Static SystemParameters.CaptionHeight}" />
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Window">
                <DockPanel LastChildFill="True">
                    <Border Background="LightBlue" DockPanel.Dock="Top" 
                            Height="{x:Static SystemParameters.CaptionHeight}" x:Name="titlebar">
                        <Grid>
                            <TextBlock Text="{TemplateBinding Title}" 
                                        Margin="10,0,0,0"
                                        VerticalAlignment="Center">
                                <TextBlock.Effect>
                                    <DropShadowEffect Color="White" ShadowDepth="3"/>
                                </TextBlock.Effect>
                            </TextBlock>
                        </Grid>
                    </Border>
                    <Border Background="{TemplateBinding Background}" BorderBrush="LightGray" 
                            BorderThickness="1" Padding="4">
                        <ContentPresenter/>
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

usage

<Window x:Class="CSharpWPF.View" 
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                Title="MainWindow" 
                Style="{StaticResource CustomTitleBar}" >
    <TextBlock Text="Window content"/>
</Window>

`How to implement in your code`

After looking at your code, I did manage to implement it with very little changes

Changes are

File: `CustomChrome.cs`

line 41: change `CaptionHeight = 36`, currently it is 0. this should be equal to your title bar height

var chrome = new WindowChrome() { GlassFrameThickness = new Thickness(-1), CaptionHeight = 36 };

line 60: remove `((FrameworkElement)sender).MouseDown += TitleBar_MouseDown;` as not required

line 70: remove no more used event `TitleBar_MouseDown`

File: `CornerButtons.xaml`

line 13: add `WindowChrome.IsHitTestVisibleInChrome="True"` to `StackPanel`

    <StackPanel SnapsToDevicePixels="True" Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True">

File: `MainWindow.xaml`

line 17: add `WindowChrome.IsHitTestVisibleInChrome="True"` to `StackPanel`

<cc:CornerButtons Grid.Column="2">
    <StackPanel Orientation="Horizontal"
                WindowChrome.IsHitTestVisibleInChrome="True">

this is all, and your app will have a normal title bar without need to handle custom logic

Problem

I have a custom title bar and with the window style set to none. On the click of the title bar I check to see if it is a double click (that does window maximize and restore) if it is not double clicked I do `Window.DragMove`. This works great for the snapping to the side and top. But when I try to drag the window when it is maximized (which would normally restore the window down), it doesn't do anything. Here is my code: ``` static Window Window { get { return Application.Current.MainWindow; } } /// <summary> /// TitleBar_MouseDown - Drag if single-click, resize if double-click /// </summary> private static void TitleBar_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) { if (e.ClickCount == 2) { AdjustWindowSize(); } else { Window.DragMove();//Here is where I do the drag move } } } /// <summary> /// Adjusts the WindowSize to correct parameters when Maximize button is clicked /// </summary> internal static void AdjustWindowSize() { if (Window.WindowState == WindowState.Maximized) { SystemCommands.RestoreWindow(Window); } else { SystemCommands.MaximizeWindow(Window); } } #region Button Events /// <summary> /// CloseButton_Clicked /// </summary> public static void Close() { SystemCommands.CloseWindow(Window); } /// <summary> /// MaximizedButton_Clicked /// </summary> public static void Maximize() { AdjustWindowSize(); } /// <summary> /// Minimized Button_Clicked /// </summary> public static void Minimize() { SystemCommands.MinimizeWindow(Window); } #endregion ``` Modern UI and MahApps.Metro does it somehow and I looked at their source code briefly but could not find how they do it. Thanks in advance.

Original source