I don't know if there is any easy way, without using external components, but I just wanted to change the background color of a screen in WPF. It was a saga. I had to: 1. Create custom buttons (with the same font used in Windows 10) 2. Disable WindowStyle and ResizeMode. 3. Define functionality to move the window (DragWindow) with 1 click, restore the window (Maximizing or Restoring) with 2 clicks. 4. Resize mode (custom) using Rectangles 5. Set maximum window size, so as not to overlap the taskbar. 6. Create icon and Text to use as Title of the application.
Created
June 8, 2020 01:47
-
-
Save fabric-io-rodrigues/4cd83f1aeb41dc8f60fe9535184cbe10 to your computer and use it in GitHub Desktop.
Changing WPF title bar background color - HardMode :-)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Application x:Class="BasicApp.App" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
Startup="Application_Startup" | |
Exit="Application_Exit"> | |
<Application.Resources> | |
<Style x:Key="CaptionButtonStyleDefault" TargetType="Button"> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="Button"> | |
<Grid x:Name="LayoutRoot" Background="Transparent" Width="46" Height="30"> | |
<TextBlock x:Name="txt" Text="{TemplateBinding Content}" FontFamily="Segoe MDL2 Assets" FontSize="10" | |
Foreground="#E5E5E5" HorizontalAlignment="Center" VerticalAlignment="Center" | |
RenderOptions.ClearTypeHint="Auto" TextOptions.TextRenderingMode="Aliased" TextOptions.TextFormattingMode="Display"/> | |
</Grid> | |
<ControlTemplate.Triggers> | |
<Trigger Property="IsMouseOver" Value="True"> | |
<Setter TargetName="LayoutRoot" Property="Background" Value="#E5E5E5"/> | |
<Setter TargetName="txt" Property="Foreground" Value="#000000"/> | |
</Trigger> | |
</ControlTemplate.Triggers> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
</Style> | |
<Style x:Key="CaptionButtonStyleClose" TargetType="Button"> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="Button"> | |
<Grid x:Name="LayoutRoot" Background="Transparent" Width="46" Height="30"> | |
<TextBlock x:Name="txt" Text="{TemplateBinding Content}" FontFamily="Segoe MDL2 Assets" FontSize="10" | |
Foreground="#E5E5E5" HorizontalAlignment="Center" VerticalAlignment="Center" | |
RenderOptions.ClearTypeHint="Auto" TextOptions.TextRenderingMode="Aliased" TextOptions.TextFormattingMode="Display"/> | |
</Grid> | |
<ControlTemplate.Triggers> | |
<Trigger Property="IsMouseOver" Value="True"> | |
<Setter TargetName="LayoutRoot" Property="Background" Value="#E81123"/> | |
<Setter TargetName="txt" Property="Foreground" Value="#FFFFFF"/> | |
</Trigger> | |
</ControlTemplate.Triggers> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
</Style> | |
<Style x:Key="MinimizeButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyleDefault}"> | |
<Setter Property="Content" Value=""/> | |
</Style> | |
<Style x:Key="MaximizeButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyleDefault}"> | |
<Setter Property="Content" Value=""/> | |
</Style> | |
<Style x:Key="RestoreButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyleDefault}"> | |
<Setter Property="Content" Value=""/> | |
</Style> | |
<Style x:Key="CloseButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyleClose}"> | |
<Setter Property="Content" Value=""/> | |
</Style> | |
</Application.Resources> | |
</Application> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window x:Class="BasicApp.Window1" | |
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" | |
mc:Ignorable="d" | |
Title="Window1" Height="450" Width="800" | |
MinHeight="30" MinWidth="250" WindowStyle="None" ResizeMode="CanMinimize" WindowState="Maximized"> | |
<Window.Resources> | |
<Style x:Key="RectBorderStyle" TargetType="Rectangle"> | |
<Setter Property="Focusable" Value="False" /> | |
<Setter Property="Fill" Value="Transparent" /> | |
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=Window}}" /> | |
<EventSetter Event="MouseLeftButtonDown" Handler="Resize_Init"/> | |
<EventSetter Event="MouseLeftButtonUp" Handler="Resize_End"/> | |
<EventSetter Event="MouseMove" Handler="Resizeing_Form"/> | |
</Style> | |
</Window.Resources> | |
<Grid> | |
<Grid MouseDown="StackPanel_MouseDown" VerticalAlignment="Top" Margin="0" Background="#3e4a59"> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="Auto" /> | |
<ColumnDefinition Width="*" /> | |
<ColumnDefinition Width="Auto" /> | |
</Grid.ColumnDefinitions> | |
<Image x:Name="HeaderIcon" Grid.Column="0" Width="20" Height="20" Margin="5, 4, 5, 4" HorizontalAlignment="Left" /> | |
<TextBlock x:Name="HeaderTitle" Grid.Column="1" Margin="5" TextAlignment="Left" Foreground="#FFFFFF" FontSize="13" HorizontalAlignment="Left" /> | |
<StackPanel Grid.Column="2" VerticalAlignment="Top" Orientation="Horizontal" HorizontalAlignment="Right"> | |
<Button x:Name="MinimizeButton" Style="{DynamicResource MinimizeButtonStyle}" Click="MinimizeWindow" KeyboardNavigation.IsTabStop="False" /> | |
<Button x:Name="MaximizeButton" Style="{DynamicResource MaximizeButtonStyle}" Click="MaximizeClick" KeyboardNavigation.IsTabStop="False" /> | |
<Button x:Name="CloseButton" Style="{DynamicResource CloseButtonStyle}" Click="CloseButton_Click" KeyboardNavigation.IsTabStop="False" /> | |
</StackPanel> | |
</Grid> | |
<Grid Margin="0,30,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="LightBlue"> | |
<!-- Here --> | |
</Grid> | |
<Rectangle x:Name="leftSizeGrip" Width="7" HorizontalAlignment="Left" Cursor="SizeWE" Style="{StaticResource RectBorderStyle}" /> | |
<Rectangle x:Name="rightSizeGrip" Width="7" HorizontalAlignment="Right" Cursor="SizeWE" Style="{StaticResource RectBorderStyle}" /> | |
<Rectangle x:Name="topSizeGrip" Height="7" VerticalAlignment="Top" Cursor="SizeNS" Style="{StaticResource RectBorderStyle}" /> | |
<Rectangle x:Name="bottomSizeGrip" Height="7" VerticalAlignment="Bottom" Cursor="SizeNS" Style="{StaticResource RectBorderStyle}" /> | |
<!-- Corners --> | |
<Rectangle Name="topLeftSizeGrip" Width="7" Height="7" HorizontalAlignment="Left" VerticalAlignment="Top" Cursor="SizeNWSE" Style="{StaticResource RectBorderStyle}" /> | |
<Rectangle Name="bottomRightSizeGrip" Width="7" Height="7" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE" Style="{StaticResource RectBorderStyle}" /> | |
<Rectangle Name="topRightSizeGrip" Width="7" Height="7" HorizontalAlignment="Right" VerticalAlignment="Top" Cursor="SizeNESW" Style="{StaticResource RectBorderStyle}" /> | |
<Rectangle Name="bottomLeftSizeGrip" Width="7" Height="7" HorizontalAlignment="Left" VerticalAlignment="Bottom" Cursor="SizeNESW" Style="{StaticResource RectBorderStyle}" /> | |
</Grid> | |
</Window> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
using System.Windows; | |
using System.Windows.Input; | |
using System.Windows.Media.Imaging; | |
using System.Windows.Shapes; | |
namespace BasicApp | |
{ | |
/// <summary> | |
/// Interaction logic for Window1.xaml | |
/// </summary> | |
public partial class Window1 : Window | |
{ | |
#region ResizeWindows | |
bool ResizeInProcess = false; | |
private void Resize_Init(object sender, MouseButtonEventArgs e) | |
{ | |
Rectangle senderRect = sender as Rectangle; | |
if (senderRect != null) | |
{ | |
ResizeInProcess = true; | |
senderRect.CaptureMouse(); | |
} | |
} | |
private void Resize_End(object sender, MouseButtonEventArgs e) | |
{ | |
Rectangle senderRect = sender as Rectangle; | |
if (senderRect != null) | |
{ | |
ResizeInProcess = false; ; | |
senderRect.ReleaseMouseCapture(); | |
} | |
} | |
private void Resizeing_Form(object sender, MouseEventArgs e) | |
{ | |
if (ResizeInProcess) | |
{ | |
Rectangle senderRect = sender as Rectangle; | |
Window mainWindow = senderRect.Tag as Window; | |
if (senderRect != null) | |
{ | |
double width = e.GetPosition(mainWindow).X; | |
double height = e.GetPosition(mainWindow).Y; | |
senderRect.CaptureMouse(); | |
if (senderRect.Name.ToLower().Contains("right")) | |
{ | |
width += 5; | |
if (width > 0) | |
mainWindow.Width = width; | |
} | |
if (senderRect.Name.ToLower().Contains("left")) | |
{ | |
width -= 5; | |
mainWindow.Left += width; | |
width = mainWindow.Width - width; | |
if (width > 0) | |
{ | |
mainWindow.Width = width; | |
} | |
} | |
if (senderRect.Name.ToLower().Contains("bottom")) | |
{ | |
height += 5; | |
if (height > 0) | |
mainWindow.Height = height; | |
} | |
if (senderRect.Name.ToLower().Contains("top")) | |
{ | |
height -= 5; | |
mainWindow.Top += height; | |
height = mainWindow.Height - height; | |
if (height > 0) | |
{ | |
mainWindow.Height = height; | |
} | |
} | |
} | |
} | |
} | |
#endregion | |
#region TitleButtons | |
private void MinimizeWindow(object sender, RoutedEventArgs e) | |
{ | |
App.Current.MainWindow.WindowState = WindowState.Minimized; | |
} | |
private void MaximizeClick(object sender, RoutedEventArgs e) | |
{ | |
AdjustWindowSize(); | |
} | |
private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e) | |
{ | |
if (e.ChangedButton == MouseButton.Left) | |
{ | |
if (e.ClickCount == 2) | |
{ | |
AdjustWindowSize(); | |
} | |
else | |
{ | |
App.Current.MainWindow.DragMove(); | |
} | |
} | |
} | |
private void AdjustWindowSize() | |
{ | |
if (App.Current.MainWindow.WindowState == WindowState.Maximized) | |
{ | |
App.Current.MainWindow.WindowState = WindowState.Normal; | |
MaximizeButton.Content = ""; | |
} | |
else if (App.Current.MainWindow.WindowState == WindowState.Normal) | |
{ | |
App.Current.MainWindow.WindowState = WindowState.Maximized; | |
MaximizeButton.Content = ""; | |
} | |
} | |
private void CloseButton_Click(object sender, RoutedEventArgs e) | |
{ | |
App.Current.MainWindow.Close(); | |
} | |
#endregion | |
public Window1() | |
{ | |
InitializeComponent(); | |
//limit for height to not overlay system taskbar | |
this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight; | |
HeaderIcon.Source = BitmapFrame.Create(new Uri("pack://application:,,,/IconApp.ico", UriKind.RelativeOrAbsolute)); | |
HeaderTitle.Text = "Title of Window"; | |
} | |
} | |
} |
Author
fabric-io-rodrigues
commented
Jun 8, 2020
When Maximized, the lower edge of the window goes behind the TaskBar, obscuring whatever is at the bottom edge of the window.
When resizing window, the Resize_End is called before the mouse button is released.
adding this line to the top of Resize_End, prevent this issue
if (e.LeftButton == MouseButtonState.Pressed) return;
If you need to change ResizeMode="CanMinimize"
to ResizeMode="CanResize"
, don't forget to add the <WindowChrome.WindowChrome>
tag inside the <Window>
tag
<Window ...>
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>
...
</Window>
That will remove the top white border.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment