標題列自訂
Windows 提供每個視窗的預設標題列,並可讓您自訂以符合您應用程式的風格。 預設標題列隨附一些標準元件和核心功能,例如拖曳和調整視窗大小。
如需自訂應用程式標題列、可接受的標題列區域內容和建議 UI 模式的指引,請參閱標題列設計文章。
注意
本文介紹如何為使用 UWP 和 WinUI 2 的應用程式自訂標題列。 使用 Windows App SDK 和 WinUI 3 的應用程式,請參閱 Windows App SDK 的標題列自訂。
如果您正在考慮將 UWP 應用程式移轉到 Windows App SDK,請查看我們的視窗功能移轉指南。 如需詳細資訊,請參閱 視窗功能移轉。
- 適用於:UWP/WinUI 2
- 重要 API:ApplicationView.TitleBar 屬性、ApplicationViewTitleBar 類別、CoreApplicationViewTitleBar 類別
此清單描述標準標題列的元件。
- 標題列矩形
- 標題文字
- 系統選單 - 按一下應用程式圖示或以滑鼠右鍵按下標題列來存取
- 標題控制項
- 最小化按鈕
- 最大化/還原按鈕
- 關閉按鈕
在 UWP 應用程式中,您可以使用 ApplicationView 和 CoreApplicationView 類別的成員自訂標題列。 有多個 API 可根據所需的自訂層級,逐步修改標題列的外觀。
注意
用於 UWP 應用程式中次要視窗的 Windows.UI.WindowManagement.AppWindow 類別不支援標題列自訂。 若要自訂使用次要視窗的 UWP 應用程式的標題列,請使用 ApplicationView,如使用 ApplicationView 顯示多個檢視中所述。
您可以套用至標題列的自訂層級有兩種:將次要修改套用至預設標題列,或將應用程式畫布延伸至標題列區域,並提供完全自訂的內容。
針對簡單的自訂,例如變更標題列色彩,您可以在應用程式視窗的標題列物件上設定屬性,以指定您想要用於標題列元素的色彩。 在此情況下,系統會保留標題列所有其他層面的責任,例如繪製應用程式標題和定義拖曳區域。
另一個選項是隱藏預設標題列,並將它取代為您自己的自訂內容。 例如,您可以將文字、搜尋方塊或自訂功能表放在標題列區域中。 您也必須使用此選項,將材料底圖 (如 Mica) 延伸至標題列區域。
當您選擇完全自訂時,您必須負責將內容放入標題列區域,而且您可以定義自己的拖曳區域。 標題控制項 (系統 [關閉]、[最小化] 和 [最大化] 按鈕) 仍可供系統使用及處理,但應用程式標題等元素則不是。 您必須視應用程式需要自行建立這些元素。
如果您只想自訂標題列色彩或圖示,您可以在應用程式視窗的標題列物件上設定屬性。
預設情況下,標題列會將應用程式的顯示名稱做為視窗標題顯示。 顯示名稱 Package.appxmanifest
在檔案中設定。
若要將自訂文字新增至標題,請將 ApplicationView.Title 屬性設為文字值,如下所示。
public MainPage()
{
this.InitializeComponent();
ApplicationView.GetForCurrentView().Title = "Custom text";
}
您的文字將會新增到視窗標題前面,該標題將顯示為「自訂文字 - 應用程式顯示名稱」。 若要顯示沒有應用程式顯示名稱的自訂標題,您必須取代預設標題列,如完整自訂區段所示。
此範例示範如何取得 ApplicationViewTitleBar 執行個體,並設定其色彩屬性。
您可以在對 Window.Activate 的呼叫之後,將此程式碼置於您應用程式的 OnLaunched 方法 (App.xaml.cs) 中,或是將它置於您應用程式的第一個頁面。
// using Windows.UI;
// using Windows.UI.ViewManagement;
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
// Set active window colors
titleBar.ForegroundColor = Colors.White;
titleBar.BackgroundColor = Colors.Green;
titleBar.ButtonForegroundColor = Colors.White;
titleBar.ButtonBackgroundColor = Colors.SeaGreen;
titleBar.ButtonHoverForegroundColor = Colors.White;
titleBar.ButtonHoverBackgroundColor = Colors.DarkSeaGreen;
titleBar.ButtonPressedForegroundColor = Colors.Gray;
titleBar.ButtonPressedBackgroundColor = Colors.LightGreen;
// Set inactive window colors
titleBar.InactiveForegroundColor = Colors.Gainsboro;
titleBar.InactiveBackgroundColor = Colors.SeaGreen;
titleBar.ButtonInactiveForegroundColor = Colors.Gainsboro;
titleBar.ButtonInactiveBackgroundColor = Colors.SeaGreen;
設定標題列色彩時,有幾個事項需要注意:
- 不會將按鈕背景色彩套用至 [關閉] 按鈕的 [暫留] 和 [已按下] 狀態。 [關閉] 按鈕一律會針對這些狀態使用系統定義的色彩。
- 設定色彩屬性,將
null
重設為預設系統色彩。 - 您無法設定透明色彩。 會忽略色彩的 Alpha 色板。
Windows 可讓使用者選擇將選取的輔色套用至標題列。 如果您設定任何標題列色彩,建議您明確設定好所有色彩。 這可確保不會因為使用者定義的色彩設定而發生非預期的色彩組合。
當您改為標題列完全自訂時,應用程式的工作區會延伸為涵蓋整個視窗,包括標題列區域。 您必須負責整個視窗的繪製和輸入處理,但視窗仍會提供標題按鈕。
若要隱藏預設標題列,並將內容延伸到標題列區域,請將 ExtendViewIntoTitleBar 屬性設為 true
。 您可以在應用程式的 OnLaunched
方法 (App.xaml.cs),或在應用程式的第一頁中設定此屬性。
提示
請參閱完整自訂範例一節,一次查看所有程式碼。
此範例會示範如何取得 CoreApplicationViewTitleBar,並將 ExtendViewIntoTitleBar 屬性設為 true
。
using Windows.ApplicationModel.Core;
public MainPage()
{
this.InitializeComponent();
// Hide default title bar.
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.ExtendViewIntoTitleBar = true;
}
提示
當您的應用程式關閉並重新啟動時,此設定仍然會存在。 在 Visual Studio 中,如果將 ExtendViewIntoTitleBar
設為 true
,然後想要將其還原為預設值,則應明確將其設為 false
,並執行應用程式以覆寫保留的設定。
當您的應用程式延伸至標題列區域時,您必須負責定義和管理標題列的 UI。 這通常至少包含指定標題文字和拖曳區域。 標題列的拖曳區域會定義使用者可以按下視窗並拖曳來移動視窗的位置。 這也是使用者可以以滑鼠右鍵按一下以顯示系統功能表的位置。
若要深入瞭解可接受的標題列內容和建議的 UI 模式,請參閱標題列設計。
您可以透過呼叫 Window.SetTitleBar 方法,並傳入定義拖曳區域的 UIElement 來指定拖曳區域。 (UIElement
通常是包含其他元素的面板。)ExtendViewIntoTitleBar
屬性必須設定為 true
,才能使對 SetTitleBar
的呼叫產生效果。
以下是如何將 Grid
內容設定為可拖曳標題列區域。 此程式碼位於應用程式首頁的 XAML 和程式碼後置中。
<Grid x:Name="AppTitleBar" Background="Transparent">
<!-- Width of the padding columns is set in LayoutMetricsChanged handler. -->
<!-- Using padding columns instead of Margin ensures that the background
paints the area under the caption control buttons (for transparent buttons). -->
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
<Image Source="Assets/WindowIcon.png"
Grid.Column="1"
HorizontalAlignment="Left"
Width="16" Height="16"
Margin="8,0,0,0"/>
<TextBlock x:Name="AppTitleTextBlock"
Text="App title"
Style="{StaticResource CaptionTextBlockStyle}"
Grid.Column="1"
VerticalAlignment="Center"
Margin="28,0,0,0"/>
</Grid>
public MainPage()
{
this.InitializeComponent();
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.ExtendViewIntoTitleBar = true;
// Set XAML element as a drag region.
Window.Current.SetTitleBar(AppTitleBar);
}
預設情況下,系統標題列會將應用程式的顯示名稱做為視窗標題顯示。 顯示名稱在 Package.appxmanifest 檔案中設定。 您可以取得此值,並將其用於自訂標題列中,如下所示。
AppTitleTextBlock.Text = AppInfo.Current.DisplayInfo.DisplayName;
重要
您指定的拖曳區域必須要能進行點擊測試。 預設情況下,某些 UI 元素 (例如 Grid
) 在沒有設定背景時不參與點擊測試。 這代表對於某些元素,您可能需要設定透明背景筆刷。 如需詳細資訊,請參閱 VisualTreeHelper.FindElementsInHostCoordinates 的備註。
例如,如果您將方格定義為拖曳區域,請設定 Background="Transparent"
以使其可拖曳。
此方格不可拖曳 (但其中的可見元素是):<Grid x:Name="AppTitleBar">
。
這個方格看起來是一樣的,但是整個方格是可以拖曳的:<Grid x:Name="AppTitleBar" Background="Transparent">
。
您可以在應用程式頂端放置互動式控制項,例如按鈕、功能表或搜尋方塊,使其出現在標題列中。 但是,您必須遵循一些規則,以確保您的互動式元素接收使用者輸入,同時仍允許使用者移動您的視窗。
- 您必須呼叫 SetTitleBar,才能將區域定義為可拖曳的標題列區域。 如果不這樣做,系統會將預設拖曳區域設定在頁面頂端。 然後,系統將處理該區域的所有使用者輸入,並防止輸入到達您的控制項。
- 將互動式控制項放置在透過呼叫 SetTitleBar 定義的拖曳區域頂端 (具有更高的 z 順序)。 不要將互動式控制項作為傳遞給
SetTitleBar
的 UIElement 的子控制項。 將元素傳遞給SetTitleBar
後,系統會將其視為系統標題列,並處理輸入到該元素的所有指標。
在這裡,AutoSuggestBox 元素的 z 順序高於 AppTitleBar
,因此它接收使用者輸入。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid x:Name="AppTitleBar" Background="Transparent">
<!-- Width of the padding columns is set in LayoutMetricsChanged handler. -->
<!-- Using padding columns instead of Margin ensures that the background
paints the area under the caption control buttons (for transparent buttons). -->
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
<Image Source="Assets/WindowIcon.png"
Grid.Column="1"
HorizontalAlignment="Left"
Width="16" Height="16"
Margin="8,0,0,0"/>
<TextBlock x:Name="AppTitleTextBlock"
Text="App title"
Style="{StaticResource CaptionTextBlockStyle}"
Grid.Column="1"
VerticalAlignment="Center"
Margin="28,0,0,0"/>
</Grid>
<!-- This control has a higher z-order than AppTitleBar,
so it receives user input. -->
<AutoSuggestBox QueryIcon="Find"
PlaceholderText="Search"
HorizontalAlignment="Center"
Width="260" Height="32"/>
</Grid>
系統會保留應用程式視窗左上角或右上角供系統標題按鈕使用 (最小化、最大化/還原、關閉)。 系統會保留標題按鈕區域的控制項,以確保提供拖曳、最小化、最大化和關閉視窗的最低功能。 系統會針對由左至右的語言在右上方繪製 [關閉] 按鈕,而從右至左的語言則繪製於左上方。
您可以在標題控制項區域底下繪製內容,例如您的應用程式背景,但您不應該放置預期使用者能夠與之互動的任何 UI。 它不會收到任何輸入,因為是由系統處理標題控制項的輸入。
上一個範例中的這幾行會顯示 XAML 中定義標題列的填補資料行。 使用填補資料行而非邊界可確保背景塗滿標題控制按鈕下的區域 (適用於透明按鈕)。 同時使用左和右填補資料行可確保標題列在從右至左和從左至右的版面配置中都能正確運作。
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
CoreApplicationViewTitleBar 類別會傳達標題控制區域的維度和位置,讓您可以在標題列 UI 的版面配置中顯示。 每側保留區域的寬度是由 SystemOverlayLeftInset 或 SystemOverlayRightInset 屬性指定,其高度是由 Height 屬性指定。
您可以處理 LayoutMetricsChanged 事件,以回應標題按鈕大小的變更。 例如,如果應用程式版面配置從左到右變更為從右到左,就可能會發生這種情況。 處理此事件,以驗證和更新取決於標題列大小的 UI 元素的位置。
此範例示範如何調整標題列的版面配置,以適應標題列指標的變化。 AppTitleBar
、LeftPaddingColumn
和 RightPaddingColumn
在先前顯示的 XAML 中宣告。
private void CoreTitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
{
// Get the size of the caption controls and set padding.
LeftPaddingColumn.Width = new GridLength(coreTitleBar.SystemOverlayLeftInset);
RightPaddingColumn.Width = new GridLength(coreTitleBar.SystemOverlayRightInset);
}
當您將應用程式內容延伸至標題列區域時,您可以讓標題按鈕的背景變成透明,讓您的應用程式背景穿透顯示。 您通常可將背景設定為 Colors.Transparent 以取得完整的透明度。 若要部分透明度,請針對您設定屬性的 Color 設定 Alpha 色板。
這些標題列屬性可以是透明的:
- ButtonBackgroundColor
- ButtonHoverBackgroundColor
- ButtonPressedBackgroundColor
- ButtonInactiveBackgroundColor
所有其他色彩屬性都會繼續忽略 Alpha 色板。 如果 ExtendViewIntoTitleBar
設定為 false
,則所有 ApplicationViewTitleBar
色彩屬性一律會忽略 Alpha 色板。
不會將按鈕背景色彩套用至 [關閉] 按鈕的 [暫留] 和 [已按下] 狀態。 [關閉] 按鈕一律會針對這些狀態使用系統定義的色彩。
提示
Mica 是一種亮眼的材料,有助於區分聚焦的視窗。 建議您將其作為 Windows 11 中長時間存留視窗的背景。 如果您已在視窗的工作區中套用 Mica,您可以將它延伸至標題列區域,並讓 Mica 的標題按鈕透明顯示。 如需詳細資訊,請參閱 Mica 材料。
當您的視窗處於作用中或非使用中狀態時,您應該讓其明顯可區別。 您至少應該變更標題列中文字、圖示和按鈕的色彩。
請處理 CoreWindow.Activated 事件來判斷視窗的啟用狀態,並視需要更新標題列 UI。
public MainPage()
{
...
Window.Current.CoreWindow.Activated += CoreWindow_Activated;
}
private void CoreWindow_Activated(CoreWindow sender, WindowActivatedEventArgs args)
{
UISettings settings = new UISettings();
if (args.WindowActivationState == CoreWindowActivationState.Deactivated)
{
AppTitleTextBlock.Foreground =
new SolidColorBrush(settings.UIElementColor(UIElementType.GrayText));
}
else
{
AppTitleTextBlock.Foreground =
new SolidColorBrush(settings.UIElementColor(UIElementType.WindowText));
}
}
您可以呼叫 SetTitleBar,以在應用程式執行時切換至新的標題列元素。 您也可以將 null
作為參數傳遞給 SetTitleBar
,並將 ExtendViewIntoTitleBar 設為 false
以還原為預設的系統標題列。
如果您將全螢幕或精簡重疊模式支援新增至您的應用程式,則當您的應用程式在這些模式之間切換時,您可能需要變更標題列。
當您的應用程式以全螢幕或平板電腦模式 (僅限 Windows 10) 運作時,系統會隱藏標題列和標題控制項按鈕。 但是,使用者可以呼叫標題列,將其顯示為應用程式 UI 頂端的疊層。
您可以處理 CoreApplicationViewTitleBar.IsVisibleChanged 事件,以便在隱藏或呼叫標題列時收到通知,並根據需要顯示或隱藏自訂標題列內容。
此範例顯示如何處理 IsVisibleChanged
事件,以顯示和隱藏先前範例中的 AppTitleBar
元素。
public MainPage()
{
this.InitializeComponent();
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
// Register a handler for when the title bar visibility changes.
// For example, when the title bar is invoked in full screen mode.
coreTitleBar.IsVisibleChanged += CoreTitleBar_IsVisibleChanged;
}
private void CoreTitleBar_IsVisibleChanged(CoreApplicationViewTitleBar sender, object args)
{
if (sender.IsVisible)
{
AppTitleBar.Visibility = Visibility.Visible;
}
else
{
AppTitleBar.Visibility = Visibility.Collapsed;
}
}
注意
僅當您的應用程式支援時,才能進入全螢幕模式。 如需詳細資訊,請參閱 ApplicationView.IsFullScreenMode。 平板電腦模式 (僅限 Windows 10) 是受支援硬體上 Windows 10 中的使用者選項,因此使用者可以選擇在平板電腦模式下執行任何應用程式。
- 當您的視窗處於作用中或非使用中狀態時,務必確保其明顯可區別。 您至少要變更標題列中文字、圖示和按鈕的色彩。
- 務必沿著應用程式畫布頂端邊緣定義拖曳區域。 讓系統標題列的位置相符可讓使用者更容易找到。
- 務必讓定義的拖曳區域與應用程式畫布上視覺標題列 (如果有的話) 的拖曳區域相符。
此範例顯示完全自訂一節中所述的所有程式碼。
<Page
x:Class="WinUI2_ExtendedTitleBar.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinUI2_ExtendedTitleBar"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
muxc:BackdropMaterial.ApplyToRootOrPageBackground="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid x:Name="AppTitleBar" Background="Transparent">
<!-- Width of the padding columns is set in LayoutMetricsChanged handler. -->
<!-- Using padding columns instead of Margin ensures that the background
paints the area under the caption control buttons (for transparent buttons). -->
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
<Image Source="Assets/WindowIcon.png"
Grid.Column="1"
HorizontalAlignment="Left"
Width="16" Height="16"
Margin="8,0,0,0"/>
<TextBlock x:Name="AppTitleTextBlock"
Text="App title"
Style="{StaticResource CaptionTextBlockStyle}"
Grid.Column="1"
VerticalAlignment="Center"
Margin="28,0,0,0"/>
</Grid>
<!-- This control has a higher z-order than AppTitleBar,
so it receives user input. -->
<AutoSuggestBox QueryIcon="Find"
PlaceholderText="Search"
HorizontalAlignment="Center"
Width="260" Height="32"/>
<muxc:NavigationView Grid.Row="1"
IsBackButtonVisible="Collapsed"
IsSettingsVisible="False">
<StackPanel>
<TextBlock Text="Content"
Style="{ThemeResource TitleTextBlockStyle}"
Margin="12,0,0,0"/>
</StackPanel>
</muxc:NavigationView>
</Grid>
</Page>
public MainPage()
{
this.InitializeComponent();
// Hide default title bar.
CoreApplicationViewTitleBar coreTitleBar =
CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.ExtendViewIntoTitleBar = true;
// Set caption buttons background to transparent.
ApplicationViewTitleBar titleBar =
ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
// Set XAML element as a drag region.
Window.Current.SetTitleBar(AppTitleBar);
// Register a handler for when the size of the overlaid caption control changes.
coreTitleBar.LayoutMetricsChanged += CoreTitleBar_LayoutMetricsChanged;
// Register a handler for when the title bar visibility changes.
// For example, when the title bar is invoked in full screen mode.
coreTitleBar.IsVisibleChanged += CoreTitleBar_IsVisibleChanged;
// Register a handler for when the window activation changes.
Window.Current.CoreWindow.Activated += CoreWindow_Activated;
}
private void CoreTitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
{
// Get the size of the caption controls and set padding.
LeftPaddingColumn.Width = new GridLength(coreTitleBar.SystemOverlayLeftInset);
RightPaddingColumn.Width = new GridLength(coreTitleBar.SystemOverlayRightInset);
}
private void CoreTitleBar_IsVisibleChanged(CoreApplicationViewTitleBar sender, object args)
{
if (sender.IsVisible)
{
AppTitleBar.Visibility = Visibility.Visible;
}
else
{
AppTitleBar.Visibility = Visibility.Collapsed;
}
}
private void CoreWindow_Activated(CoreWindow sender, WindowActivatedEventArgs args)
{
UISettings settings = new UISettings();
if (args.WindowActivationState == CoreWindowActivationState.Deactivated)
{
AppTitleTextBlock.Foreground =
new SolidColorBrush(settings.UIElementColor(UIElementType.GrayText));
}
else
{
AppTitleTextBlock.Foreground =
new SolidColorBrush(settings.UIElementColor(UIElementType.WindowText));
}
}