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.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
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).
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.
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 :
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.
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.