Wpf Title bar

stefan zapryanov 1 Reputation point
2021-01-07T01:30:27.873+00:00

Hey! So I want to change the color of the WPF title bar(where the x and the other buttons are) but I came to the conclusion I can't change that directly in WPF without using a third-party theme(am I wrong)? Also if it's really like that I downloaded MahApps but can't figure out how to change it there as well. I don't want to choose between the default themes I want a custom color. Any idea how I can do that in WPF directly,which I prefer,or if not-in MahApps then. Also I am a beginner so if you can make it simple I aprreciate.Right now it looks like this(screw it screenshot not uploading).

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,784 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Rob Ainscough 81 Reputation points
    2021-05-06T17:09:51.657+00:00

    Am I the only one that finds the solution to "I want to change the color of the WPF title bar" consists of 182 lines of code?

    Microsoft, you are lost if you think this is viable software engineering.

    Cheers, Rob.

    3 people found this answer helpful.

  2. DaisyTian-1203 11,626 Reputation points
    2021-01-07T06:54:42.08+00:00

    You can use WindowChrome Class to describe the customizations to the non-client area of a window. You can create custom Window class and set a style for it, then you can use it as common control.

    Code demo for MyCustomeWindow.cs:

            public MyCustomeWindow()  
            {  
                DefaultStyleKey = typeof(MyCustomeWindow);  
                CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));  
                CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow, CanResizeWindow));  
                CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, MinimizeWindow, CanMinimizeWindow));  
                CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, RestoreWindow, CanResizeWindow));  
                CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu));  
            }  
      
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)  
            {  
                base.OnMouseLeftButtonDown(e);  
                if (e.ButtonState == MouseButtonState.Pressed)  
                    DragMove();  
            }  
      
            protected override void OnContentRendered(EventArgs e)  
            {  
                base.OnContentRendered(e);  
                if (SizeToContent == SizeToContent.WidthAndHeight)  
                    InvalidateMeasure();  
            }  
      
            #region Window Commands  
      
            private void CanResizeWindow(object sender, CanExecuteRoutedEventArgs e)  
            {  
                e.CanExecute = ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip;  
            }  
      
            private void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)  
            {  
                e.CanExecute = ResizeMode != ResizeMode.NoResize;  
            }  
      
            private void CloseWindow(object sender, ExecutedRoutedEventArgs e)  
            {  
                this.Close();  
            }  
      
            private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)  
            {  
                SystemCommands.MaximizeWindow(this);  
            }  
      
            private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)  
            {  
                SystemCommands.MinimizeWindow(this);  
            }  
      
            private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)  
            {  
                SystemCommands.RestoreWindow(this);  
            }  
      
      
            private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)  
            {  
                var element = e.OriginalSource as FrameworkElement;  
                if (element == null)  
                    return;  
      
                var point = WindowState == WindowState.Maximized ? new Point(0, element.ActualHeight)  
                    : new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);  
                point = element.TransformToAncestor(this).Transform(point);  
                SystemCommands.ShowSystemMenu(this, point);  
            }  
      
            #endregion  
        }  
    

    Then you can create a style for custom window in dictionary:

     <!--DataTemplate for  CloseWhite/MaximizeWhite/MinimizedWhite/RestoreWhite  -->  
              
    		  
    		 <!--Style for  MinimizeButtonStyle/RestoreButtonStyle/MaximizeButtonStyle/MinimizedWhite/CloseButtonStyle/WindowTitleBarButtonStyle  -->  
            
     <Style x:Key="MyWindowStyle" TargetType="{x:Type local:MyCustomeWindow}">  
      
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />  
                <Setter Property="Background" Value="#FFF1F1F1" />  
                <Setter Property="BorderBrush" Value="#FF464775" />  
                <Setter Property="WindowChrome.WindowChrome">  
                    <Setter.Value>  
                        <WindowChrome UseAeroCaptionButtons="False"  
                                  CaptionHeight="{Binding Path=(SystemParameters.WindowNonClientFrameThickness).Top}" />  
                    </Setter.Value>  
                </Setter>  
               
                <Setter Property="Template">  
                    <Setter.Value>  
                        <ControlTemplate TargetType="{x:Type local:MyCustomeWindow}">  
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" x:Name="WindowBorder">  
                                <Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}">  
                                    <Grid.RowDefinitions>  
                                        <RowDefinition Height="Auto" />  
                                        <RowDefinition Height="*" />  
                                    </Grid.RowDefinitions>  
                                    <Grid x:Name="WindowTitlePanel"  
                                          Height="{Binding Path=(SystemParameters.WindowNonClientFrameThickness).Top}"  
                                          Background="{TemplateBinding BorderBrush}"  
                                          Margin="0,-1,0,0">  
                                        <Grid.ColumnDefinitions>  
                                            <ColumnDefinition Width="*" />  
                                            <ColumnDefinition Width="Auto" />  
                                        </Grid.ColumnDefinitions>  
      
                                        <StackPanel Orientation="Horizontal">  
                                            <Image Source="{TemplateBinding Icon}"  
                                                   VerticalAlignment="Center"  
                                                   Margin="5,0,0,0"  
                                                   Height="{x:Static SystemParameters.SmallIconHeight}"  
                                                   Width="{x:Static SystemParameters.SmallIconWidth}"  
                                                   WindowChrome.IsHitTestVisibleInChrome="True">  
                                            </Image>  
      
                                            <ContentControl IsTabStop="False"  
                                                        Margin="5,0,0,0"  
                                                        Foreground="White"  
                                                        HorizontalAlignment="Center"  
                                                        VerticalAlignment="Center"  
                                                        FontSize="{DynamicResource {x:Static SystemFonts.CaptionFontSizeKey}}"  
                                                        Content="{TemplateBinding Title}" />  
                                        </StackPanel>  
                                        <StackPanel x:Name="WindowCommandButtonsPanel"  
                                                Grid.Column="1"  
                                                HorizontalAlignment="Right"  
                                                VerticalAlignment="Stretch"  
                                                Background="Transparent"  
                                                Orientation="Horizontal"  
                                                WindowChrome.IsHitTestVisibleInChrome="True"  
                                                Margin="0,0,-1,0">  
                                            <ContentPresenter Content="{Binding FunctionBar, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"  
                                                          Focusable="False" />  
                                            <Button x:Name="MinimizeButton" Style="{StaticResource MinimizeButtonStyle}" />  
                                            <Grid Margin="1,0,1,0">  
                                                <Button x:Name="RestoreButton" Style="{StaticResource RestoreButtonStyle}" Visibility="Collapsed" />  
                                                <Button x:Name="MaximizeButton" Style="{StaticResource MaximizeButtonStyle}" />  
                                            </Grid>  
                                            <Button x:Name="CloseButton"  Background="Red" Style="{StaticResource CloseButtonStyle}" />  
                                        </StackPanel>  
                                    </Grid>  
                                    <AdornerDecorator Grid.Row="1" KeyboardNavigation.IsTabStop="False">  
                                        <ContentPresenter Content="{TemplateBinding Content}" x:Name="MainContentPresenter" KeyboardNavigation.TabNavigation="Cycle" />  
                                    </AdornerDecorator>  
                                    <ResizeGrip x:Name="ResizeGrip"  
                                            HorizontalAlignment="Right"  
                                            VerticalAlignment="Bottom"  
                                            Grid.Row="1"  
                                            IsTabStop="False"  
                                            Visibility="Hidden"  
                                            WindowChrome.ResizeGripDirection="BottomRight" />  
                                </Grid>  
                            </Border>  
      
                        </ControlTemplate>  
                    </Setter.Value>  
                </Setter>  
            </Style>  
    

    Then you can use it like below:

    <local:MyCustomeWindow   
            x:Class="WpfTitleStyle.MainWindow"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfTitleStyle"  
            Icon="/pointer.png"  
            mc:Ignorable="d"  
            Style="{StaticResource MyWindowStyle}"  
            Title="MainWindow" Height="450" Width="800">  
        
        <Grid >  
            <TextBlock Text="This is custom Window style." FontSize="25"  VerticalAlignment="Center" HorizontalAlignment="Center"/>  
        </Grid>  
    </local:MyCustomeWindow>  
      
    public partial class MainWindow : MyCustomeWindow  
        {  
            public MainWindow()  
            {  
                InitializeComponent();  
            }              
        }  
    

    The result picture is :
    54199-capture.png


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. Emon Haque 3,176 Reputation points
    2021-06-02T08:13:57.24+00:00

    Creating custom window this way is easier:

    class RootWindow : Window  
    {  
        double radius = 5;  
        Border windowBorder, titleBar;  
        Grid contentGrid, titlebarIconGrid;  
        ActionButton close, minimize, maxRestore;  
        public RootWindow() {  
            Height = 800;  
            Width = 1200;  
            WindowStartupLocation = WindowStartupLocation.CenterScreen;  
            WindowStyle = WindowStyle.None;  
            AllowsTransparency = true;  
            Title = "Rent Manager";  
            WindowChrome.SetWindowChrome(this, new WindowChrome() {  
                ResizeBorderThickness = new Thickness(0, 0, 5, 5),  
                CaptionHeight = 0  
            });  
            addTitleIcons();  
            titleBar = new Border() {  
                CornerRadius = new CornerRadius(radius, radius, 0, 0),  
                Background = Brushes.LightGray,  
                Height = 32,  
                Effect = new DropShadowEffect() { BlurRadius = 5, Opacity = 0.5, Direction = -90 },  
                Child = titlebarIconGrid  
            };  
            contentGrid = new Grid() {  
                RowDefinitions = {  
                    new RowDefinition() { Height = GridLength.Auto },  
                    new RowDefinition()  
                },  
                Children = { titleBar }  
            };  
            windowBorder = new Border() {  
                Background = Brushes.White,  
                CornerRadius = new CornerRadius(radius),  
                BorderThickness = new Thickness(1),  
                BorderBrush = Brushes.LightBlue,  
                Child = contentGrid  
            };  
            AddVisualChild(windowBorder);  
            titleBar.MouseLeftButtonDown += handleResize;  
            titleBar.MouseMove += move;  
        }  
        void move(object sender, MouseEventArgs e) {  
            if (e.LeftButton == MouseButtonState.Pressed) DragMove();  
        }  
        void handleResize(object sender, MouseButtonEventArgs e) {  
            if (e.ClickCount == 2) resize();  
        }  
        void addTitleIcons() {  
            close = new ActionButton() {  
                Width = 24,  
                Height = 24,  
                ToolTip = "Close",  
                Margin = new Thickness(0, 0, 5, 0),  
                Icon = Icons.CloseCircle,  
                Command = Application.Current.Shutdown  
            };  
            maxRestore = new ActionButton() {  
                Width = 18,  
                Height = 18,  
                ToolTip = "Maximize",  
                Margin = new Thickness(0, 0, 5, 0),  
                Icon = Icons.Maximize,  
                Command = resize  
            };  
            minimize = new ActionButton() {  
                Width = 18,  
                Height = 18,  
                ToolTip = "Minimize",  
                Margin = new Thickness(0, 0, 5, 0),  
                Icon = Icons.Minimize,  
                Command = () => WindowState = WindowState.Minimized  
            };  
            Grid.SetColumn(close, 3);  
            Grid.SetColumn(maxRestore, 2);  
            Grid.SetColumn(minimize, 1);  
            titlebarIconGrid = new Grid() {  
                ColumnDefinitions = {  
                    new ColumnDefinition(),  
                    new ColumnDefinition(){ Width = GridLength.Auto },  
                    new ColumnDefinition(){ Width = GridLength.Auto },  
                    new ColumnDefinition(){ Width = GridLength.Auto }  
                },  
                Children = { close, maxRestore, minimize }  
            };  
        }  
        void resize() {  
            if (WindowState == WindowState.Maximized) {  
                ResizeMode = ResizeMode.CanResizeWithGrip;  
                WindowState = WindowState.Normal;  
                maxRestore.Icon = Icons.Maximize;  
                maxRestore.ToolTip = "Maximize";  
            }  
            else {  
                ResizeMode = ResizeMode.NoResize;  
                WindowState = WindowState.Maximized;  
                maxRestore.Icon = Icons.Restore;  
                maxRestore.ToolTip = "Restore";  
            }  
        }  
        protected override void OnContentChanged(object oldContent, object newContent) {  
            var content = newContent as FrameworkElement;  
            Grid.SetRow(content, 1);  
            contentGrid.Children.Add(content);  
        }  
        protected override Size ArrangeOverride(Size arrangeBounds) {  
            windowBorder.Width = arrangeBounds.Width;  
            windowBorder.Height = arrangeBounds.Height;  
            windowBorder.Measure(arrangeBounds);  
            windowBorder.Arrange(new Rect(windowBorder.DesiredSize));  
            return windowBorder.DesiredSize;  
        }  
        protected override Visual GetVisualChild(int index) => windowBorder;  
        protected override int VisualChildrenCount => 1;  
    }  
    

    here I've custom Buttons, ActionButton, in the titlebar. You could see how the window looks like in almost all of my recent posts.

    0 comments No comments

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.