四、WinUI3下TitleBar的自定义

  • 四、WinUI3下TitleBar的自定义已关闭评论
  • 161 次浏览
  • A+
所属分类:.NET技术
摘要

对于Windows软件开发者来说重写标题栏样式是一个很重要的事情,在WPF阶段很多人写出来性能很差的窗口,而且为了适配Win11系统的Snaplayout后性能就更差了,这篇是写WinUI3下提供的重写TitleBar的方式;


WinUI3下TitleBar的自定义

对于Windows软件开发者来说重写标题栏样式是一个很重要的事情,在WPF阶段很多人写出来性能很差的窗口,而且为了适配Win11系统的Snaplayout后性能就更差了,这篇是写WinUI3下提供的重写TitleBar的方式;

1、修改文本

public MainWindow() {     this.InitializeComponent();     Title = "Duwenlong learn App Title"; } 

可以修改默认标题栏显示文本;但是无法自定义其他内容;所有操作都请在InitializeComponent方法后执行,不然会报错;

public MainWindow() {     this.InitializeComponent();      // Hide default title bar.     ExtendsContentIntoTitleBar = true; } 

修改后我们有完整的区域用看显示内容,只是目前还比较丑而且标题栏部分不支持拖动;

2、完全自定义

通过调用 Window.SetTitleBar 方法并传入定义拖动区域的 UIElement 来指定拖动区域。

1、标题栏内容和拖动区域

代码如下:

<Window     x:Class="TitleBarCustomizationDemo.MainWindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="using:TitleBarCustomizationDemo"     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     mc:Ignorable="d">     <Grid>         <Grid.RowDefinitions>             <RowDefinition Height="Auto"/>             <RowDefinition Height="*"/>         </Grid.RowDefinitions>         <Grid x:Name="AppTitleBar">              <TextBlock x:Name="AppTitleTextBlock" Text="Duwenlong learn Now App Title"                TextWrapping="NoWrap"                Style="{StaticResource CaptionTextBlockStyle}"                 VerticalAlignment="Center"                Margin="28,6,0,6"/>         </Grid>     </Grid>  </Window>  
public MainWindow() {     this.InitializeComponent();      ExtendsContentIntoTitleBar = true;     SetTitleBar(AppTitleBar); }  

2、交互式内容

我们可以放置一些不影响用户的交互式按钮
使用XAML的嵌套语法尝试放置一些内容,我放置了一个textblock,用于在标题栏显示一个消息;

<Window     x:Class="TitleBarCustomizationDemo.MainWindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="using:TitleBarCustomizationDemo"     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     mc:Ignorable="d">     <Grid>         <Grid.RowDefinitions>             <RowDefinition Height="Auto"/>             <RowDefinition Height="*"/>         </Grid.RowDefinitions>         <Grid x:Name="AppTitleBar" >             <TextBlock x:Name="AppTitleTextBlock" Text="Duwenlong learn Now App Title"                TextWrapping="NoWrap" Margin="28,6,0,6"                Style="{StaticResource CaptionTextBlockStyle}"                 VerticalAlignment="Center"                />             <TextBlock  Margin="28,6,0,6" Text="1 problem to be fixed" Width="220"/>         </Grid>     </Grid>  </Window> 

4、系统标题按钮的颜色和透明度

将应用内容扩展到标题栏区域时,可以使标题按钮的背景透明,我默认设置了WindowCaptionBackground为透明色

 <Application     x:Class="TitleBarCustomizationDemo.App"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="using:TitleBarCustomizationDemo">     <Application.Resources>         <ResourceDictionary>             <ResourceDictionary.MergedDictionaries>                 <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />                 <!-- Other merged dictionaries here -->             </ResourceDictionary.MergedDictionaries>             <!-- Other app resources here -->             <SolidColorBrush x:Key="WindowCaptionBackground">Transparent</SolidColorBrush>             <SolidColorBrush x:Key="WindowCaptionBackgroundDisabled">LightGreen</SolidColorBrush>             <SolidColorBrush x:Key="WindowCaptionForeground">Red</SolidColorBrush>             <SolidColorBrush x:Key="WindowCaptionForegroundDisabled">Pink</SolidColorBrush>          </ResourceDictionary>     </Application.Resources> </Application>  

5、当窗口处于非活动状态时,调暗标题栏

<Application     x:Class="TitleBarCustomizationDemo.App"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="using:TitleBarCustomizationDemo">     <Application.Resources>         <ResourceDictionary>             <ResourceDictionary.MergedDictionaries>                 <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />                 <!-- Other merged dictionaries here -->             </ResourceDictionary.MergedDictionaries>             <!-- Other app resources here -->             <!-- <SolidColorBrush x:Key="WindowCaptionBackground">Transparent</SolidColorBrush> -->             <SolidColorBrush x:Key="WindowCaptionBackground">Green</SolidColorBrush>             <SolidColorBrush x:Key="WindowCaptionBackgroundDisabled">LightGreen</SolidColorBrush>             <SolidColorBrush x:Key="WindowCaptionForeground">Red</SolidColorBrush>             <SolidColorBrush x:Key="WindowCaptionForegroundDisabled">Pink</SolidColorBrush>          </ResourceDictionary>     </Application.Resources> </Application>  
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Data; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Navigation; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections;  // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info.  namespace TitleBarCustomizationDemo {     /// <summary>     /// An empty window that can be used on its own or navigated to within a Frame.     /// </summary>     public sealed partial class MainWindow : Window     {         public MainWindow()         {             this.InitializeComponent();              ExtendsContentIntoTitleBar = true;             SetTitleBar(AppTitleBar);             Activated += MainWindow_Activated;         }          private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)         {             if (args.WindowActivationState == WindowActivationState.Deactivated)             {                 AppTitleTextBlock.Foreground =                     (SolidColorBrush)App.Current.Resources["WindowCaptionForegroundDisabled"];             }             else             {                 AppTitleTextBlock.Foreground =                     (SolidColorBrush)App.Current.Resources["WindowCaptionForeground"];             }         }     } }  

6、重置标题栏

可以在应用运行时调用 SetTitleBar 切换到新的标题栏元素。或者恢复为默认;

<Window     x:Class="TitleBarCustomizationDemo.MainWindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="using:TitleBarCustomizationDemo"     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     mc:Ignorable="d">     <Grid>         <Grid.RowDefinitions>             <RowDefinition Height="Auto"/>             <RowDefinition Height="*"/>         </Grid.RowDefinitions>         <Grid x:Name="AppTitleBar" >              <TextBlock x:Name="AppTitleTextBlock" Text="Duwenlong learn Now App Title"                TextWrapping="NoWrap" Margin="28,6,0,6"                 Style="{StaticResource CaptionTextBlockStyle}"                 VerticalAlignment="Center"                />             <TextBlock  Margin="28,6,0,6" Text="1 problem to be fixed" Width="220"/>         </Grid>         <Button Grid.Row="1" Content="Click Me" Click="Button_Click"/>     </Grid>  </Window>  
private void Button_Click(object sender, RoutedEventArgs e) {      SetTitleBar(null);     ExtendsContentIntoTitleBar = false; } 

因为使用的是Win10机器,图床又挂了所以不贴图了,Win11下会很好看。