Windows 10 个桌面应用程序的自定义标题栏颜色
Custom title bar color on Windows 10 desktop app
我在 Windows 10 上有一个混合 WinForms/WPF 桌面应用程序 运行,它仍然以 .NET 3.5 为目标。它有白天模式、dusk 模式和夜间模式。在夜间模式下,一切基本上都是黑底红字,但标题栏仍然默认为白色。
在“设置”>“个性化”>“颜色”>“在以下表面上显示强调色”中,您可以选中“标题栏”并获取要用于标题栏的强调色,然后选择深色。但是,并非我们所有的用户都知道此设置。
是否有一种简单的方法可以通过编程更改从应用程序创建的所有 Windows 的标题栏背景和前景色?如果需要,我可以使用 p/Invoke。
如果没有,我也会接受一种以编程方式全局更改标题栏颜色的方法(系统上所有 Windows),甚至可以提供自动选中该框的方法(标题上的强调色)条)并设置深色强调色。
--
编辑:可以不用设置 WindowStyle="None" 和 custom-implement 标题栏吗?这就是我已经(厌倦了)做的事情。
在 WPF(我假设是 WinForms)中,创建无边框 window 和自己创建标题栏更容易。这是执行此操作的 WPF 代码,
首先是 C#:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
private void Notify(params string[] PropertyNames)
{
foreach (string PropertyName in PropertyNames)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
public Visibility CanMaximize { get { return WindowState == WindowState.Normal ? Visibility.Visible : Visibility.Collapsed; } }
public Visibility CanRestore { get { return WindowState == WindowState.Maximized ? Visibility.Visible : Visibility.Collapsed; } }
private void CloseWindow(object sender, ExecutedRoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
{
this.WindowState = WindowState.Minimized;
}
private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
{
this.WindowState = WindowState.Maximized;
Notify("CanMaximize", "CanRestore");
}
private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
{
this.WindowState = WindowState.Normal;
Notify("CanMaximize", "CanRestore");
}
private void TitleBar_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
if (TitleBar.IsMouseDirectlyOver)
DragMove();
}
}
}
现在 XAML:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="Segoe UI Symbol"
mc:Ignorable="d" x:Name="root"
Title="MainWindow" Height="450" Width="800" WindowStyle="None">
<Window.CommandBindings>
<CommandBinding Command="SystemCommands.CloseWindowCommand" Executed="CloseWindow" CanExecute="CanExecute" />
<CommandBinding Command="SystemCommands.MinimizeWindowCommand" Executed="MinimizeWindow" CanExecute="CanExecute" />
<CommandBinding Command="SystemCommands.MaximizeWindowCommand" Executed="MaximizeWindow" CanExecute="CanExecute" />
<CommandBinding Command="SystemCommands.RestoreWindowCommand" Executed="RestoreWindow" CanExecute="CanExecute" />
</Window.CommandBindings>
<DockPanel>
<DockPanel DockPanel.Dock="Top" Background="#FF000020" x:Name="TitleBar" MouseMove="TitleBar_MouseMove">
<Image DockPanel.Dock="Left" Source="{Binding ElementName=root, Path=Icon}" Stretch="Uniform" Height="25" Width="25" Margin="2,0"/>
<Button Command="SystemCommands.CloseWindowCommand" DockPanel.Dock="Right" Margin="0" Padding="0">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
</Grid>
</Button>
<Button Command="SystemCommands.RestoreWindowCommand" DockPanel.Dock="Right" Visibility="{Binding ElementName=root, Path=CanRestore}">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
</Grid>
</Button>
<Button Command="SystemCommands.MaximizeWindowCommand" DockPanel.Dock="Right" Visibility="{Binding ElementName=root, Path=CanMaximize}">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="𐰿" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
</Grid>
</Button>
<Button Command="SystemCommands.MinimizeWindowCommand" DockPanel.Dock="Right">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="" HorizontalAlignment="Center" VerticalAlignment="Bottom" Foreground="White" />
</Grid>
</Button>
<TextBlock Text="{Binding ElementName=root, Path=Title, FallbackValue='Application Title'}" Foreground="White" VerticalAlignment="Center"/>
</DockPanel>
<Grid>
<TextBlock Text="Content goes here." VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DockPanel>
我在 Windows 10 上有一个混合 WinForms/WPF 桌面应用程序 运行,它仍然以 .NET 3.5 为目标。它有白天模式、dusk 模式和夜间模式。在夜间模式下,一切基本上都是黑底红字,但标题栏仍然默认为白色。
在“设置”>“个性化”>“颜色”>“在以下表面上显示强调色”中,您可以选中“标题栏”并获取要用于标题栏的强调色,然后选择深色。但是,并非我们所有的用户都知道此设置。
是否有一种简单的方法可以通过编程更改从应用程序创建的所有 Windows 的标题栏背景和前景色?如果需要,我可以使用 p/Invoke。
如果没有,我也会接受一种以编程方式全局更改标题栏颜色的方法(系统上所有 Windows),甚至可以提供自动选中该框的方法(标题上的强调色)条)并设置深色强调色。
--
编辑:可以不用设置 WindowStyle="None" 和 custom-implement 标题栏吗?这就是我已经(厌倦了)做的事情。
在 WPF(我假设是 WinForms)中,创建无边框 window 和自己创建标题栏更容易。这是执行此操作的 WPF 代码,
首先是 C#:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
private void Notify(params string[] PropertyNames)
{
foreach (string PropertyName in PropertyNames)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
public Visibility CanMaximize { get { return WindowState == WindowState.Normal ? Visibility.Visible : Visibility.Collapsed; } }
public Visibility CanRestore { get { return WindowState == WindowState.Maximized ? Visibility.Visible : Visibility.Collapsed; } }
private void CloseWindow(object sender, ExecutedRoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
{
this.WindowState = WindowState.Minimized;
}
private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
{
this.WindowState = WindowState.Maximized;
Notify("CanMaximize", "CanRestore");
}
private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
{
this.WindowState = WindowState.Normal;
Notify("CanMaximize", "CanRestore");
}
private void TitleBar_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
if (TitleBar.IsMouseDirectlyOver)
DragMove();
}
}
}
现在 XAML:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="Segoe UI Symbol"
mc:Ignorable="d" x:Name="root"
Title="MainWindow" Height="450" Width="800" WindowStyle="None">
<Window.CommandBindings>
<CommandBinding Command="SystemCommands.CloseWindowCommand" Executed="CloseWindow" CanExecute="CanExecute" />
<CommandBinding Command="SystemCommands.MinimizeWindowCommand" Executed="MinimizeWindow" CanExecute="CanExecute" />
<CommandBinding Command="SystemCommands.MaximizeWindowCommand" Executed="MaximizeWindow" CanExecute="CanExecute" />
<CommandBinding Command="SystemCommands.RestoreWindowCommand" Executed="RestoreWindow" CanExecute="CanExecute" />
</Window.CommandBindings>
<DockPanel>
<DockPanel DockPanel.Dock="Top" Background="#FF000020" x:Name="TitleBar" MouseMove="TitleBar_MouseMove">
<Image DockPanel.Dock="Left" Source="{Binding ElementName=root, Path=Icon}" Stretch="Uniform" Height="25" Width="25" Margin="2,0"/>
<Button Command="SystemCommands.CloseWindowCommand" DockPanel.Dock="Right" Margin="0" Padding="0">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
</Grid>
</Button>
<Button Command="SystemCommands.RestoreWindowCommand" DockPanel.Dock="Right" Visibility="{Binding ElementName=root, Path=CanRestore}">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
</Grid>
</Button>
<Button Command="SystemCommands.MaximizeWindowCommand" DockPanel.Dock="Right" Visibility="{Binding ElementName=root, Path=CanMaximize}">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="𐰿" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
</Grid>
</Button>
<Button Command="SystemCommands.MinimizeWindowCommand" DockPanel.Dock="Right">
<Grid Width="25" Height="25" Background="{Binding ElementName=TitleBar, Path=Background}">
<TextBlock Text="" HorizontalAlignment="Center" VerticalAlignment="Bottom" Foreground="White" />
</Grid>
</Button>
<TextBlock Text="{Binding ElementName=root, Path=Title, FallbackValue='Application Title'}" Foreground="White" VerticalAlignment="Center"/>
</DockPanel>
<Grid>
<TextBlock Text="Content goes here." VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DockPanel>