Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Windows poskytuje výchozí záhlaví pro každé okno a umožňuje ho přizpůsobit tak, aby odpovídal osobnosti vaší aplikace. Výchozí záhlaví obsahuje některé standardní součásti a základní funkce, jako je přetažení a změna velikosti okna.
Pokyny k přizpůsobení záhlaví vaší aplikace, přijatelného obsahu v oblasti záhlaví a doporučených vzorů uživatelského rozhraní najdete v článku o návrhu záhlaví.
Important
Tento článek ukazuje, jak přizpůsobit záhlaví aplikací, které používají Windows App SDK, a to buď s WinUI 3, nebo bez. Aplikace, které používají UWP a WinUI pro UWP, naleznete v části Přizpůsobení záhlaví pro UWP.
Important
Nový ovládací prvek Title bar byl přidán v Windows App SDK 1.7. Zjednodušuje proces přizpůsobení záhlaví.
- Applies to: Windows App SDK, desktopové aplikace WinUI
- Důležitá rozhraní API: Vlastnost AppWindow.TitleBar, třída AppWindowTitleBar, Třída AppWindow, Microsoft.UI.Xaml.Window třída, Window.ExtendsContentIntoTitleBar vlastnost, Metoda Window.SetTitleBar
Součásti záhlaví
Tento seznam popisuje součásti standardního záhlaví.
- Obdélník záhlaví
- Text nadpisu
- Ikona systému
- Systémová nabídka – přístup kliknutím na ikonu aplikace nebo kliknutím pravým tlačítkem myši na záhlaví
- Ovládací prvky titulků
- Tlačítko Minimalizovat
- Tlačítko Maximalizovat/Obnovit
- Tlačítko Zavřít
Windowing
Funkce oken v Windows App SDK je prostřednictvím třídy Microsoft.UI.Windowing.AppWindow, která je založená na modelu HWND systému Win32. Mezi AppWindow a hlavním HWND ve vaší aplikaci je přímé mapování 1:1. AppWindow a jeho související třídy poskytují rozhraní API, která umožňují spravovat mnoho aspektů oken nejvyšší úrovně vaší aplikace, včetně přizpůsobení záhlaví. Můžete upravit výchozí záhlaví, který systém Windows poskytuje, aby se sloučil se zbytkem uživatelského rozhraní, nebo rozšířit plátno aplikace do oblasti záhlaví a poskytnout vlastní obsah záhlaví.
Funkce vytváření oken v systému WinUI je prostřednictvím třídy Microsoft.UI.Xaml.Window , která je také založená na modelu Win32 HWND. Pro aplikace XAML, které používají WinUI, poskytují rozhraní API okna XAML jednodušší způsob přizpůsobení záhlaví a přitom vám umožní access rozhraní API AppWindow v případě potřeby.
Jak pracovat s AppWindow
Rozhraní AppWindow API můžete použít s libovolnou architekturou uživatelského rozhraní, kterou Windows App SDK podporuje – Win32, WPF, WinForms nebo WinUI – a můžete je postupně používat pouze pomocí potřebných rozhraní API.
Pokud jako architekturu uživatelského rozhraní aplikace používáte WinUI XAML, jsou pro vás k dispozici rozhraní API Pro Windows i AppWindow . Počínaje Windows App SDK 1.4 používají okno XAML a AppWindow stejné AppWindowTitleBar objekt pro přizpůsobení záhlaví. K získání objektu AppWindow z existujícího okna XAML použijte vlastnost Window.AppWindow . S tímto objektem AppWindow máte access rozhraní API pro přizpůsobení záhlaví.
Pokud chcete získat přístup k dalším funkcím lišty s názvem, můžete použít rozhraní AppWindow API z okna XAML takto: AppWindow.TitleBar.ForegroundColor = Colors.White;.
Pokud nepoužíváte WinUI 1.3 nebo novější, pomocí rozhraní API pro interoperabilitu získejte AppWindow a pomocí rozhraní AppWindow API upravte záhlaví. Další informace o rozhraních API pro interoperabilitu najdete v tématech Správa oken aplikací - uživatelské rozhraní a interoperabilita HWND a ukázkový projekt Windowing gallery.
Do jaké míry přizpůsobit hlavní panel
Na záhlaví můžete použít dvě úrovně přizpůsobení: použijte menší úpravy výchozího záhlaví nebo rozšiřte plátno aplikace do oblasti záhlaví a poskytněte zcela vlastní obsah.
Simple
Jednoduchým přizpůsobením, například změnou barvy záhlaví, můžete nastavit vlastnosti objektu AppWindowTitleBar a určit barvy, které chcete použít pro prvky záhlaví. V tomto případě systém uchovává odpovědnost za všechny ostatní aspekty záhlaví, jako je kreslení názvu aplikace a definování oblastí přetažení.
Full
Další možností je skrýt výchozí systémový záhlaví a nahradit ho vlastním obsahem. Do oblasti záhlaví můžete například umístit text, vyhledávací pole nebo vlastní nabídky. Tuto možnost budete také muset použít k rozšíření pozadí materiálu, jako je Mica, do oblasti záhlaví.
Když se rozhodnete pro úplné přizpůsobení, zodpovídáte za umístění obsahu do oblasti záhlaví a můžete definovat vlastní oblasti přetažení. Ovládací prvky titulků (tlačítka Zavřít, Minimalizovat a Maximalizovat) jsou stále dostupné a zpracovávané systémem, ale prvky, jako je název aplikace, nejsou. Tyto prvky budete muset vytvořit sami podle potřeby vaší aplikace.
Jednoduché přizpůsobení
Pokud chcete přizpůsobit jenom nadpis, barvy nebo ikonu záhlaví, můžete u objektu záhlaví aplikace nastavit vlastnosti.
Title
Ve výchozím nastavení se v záhlaví zobrazuje typ aplikace jako název okna (například WinUI Desktop). Název okna byste měli aktualizovat tak, aby zobrazoval smysluplný zobrazovaný název aplikace.
Aplikace XAML má zobrazovaný název, který je nastavený v souboru Package.appxmanifest. Tuto hodnotu můžete získat a použít ji k nastavení Title vlastnosti takto.
Title = AppInfo.Current.DisplayInfo.DisplayName;
Pokud chcete změnit název okna, nastavte vlastnost Window.Title na jednořádkovou textovou hodnotu, jak je znázorněno zde.
<Window
...
Title="App title">
...
</Window>
public MainWindow()
{
InitializeComponent();
Title = "App title";
}
Pokud chcete změnit název okna pomocí rozhraní AppWindow API, nastavte vlastnost AppWindow.Title na jednořádkovou textovou hodnotu, jak je znázorněno zde. Tento příklad ukazuje, jak pomocí interop API získat AppWindow, což je nutné, pokud vaše aplikace nepoužívá WinUI 1.3 nebo novější.
using Microsoft.UI; // Needed for WindowId.
using Microsoft.UI.Windowing; // Needed for AppWindow.
using WinRT.Interop; // Needed for XAML/HWND interop.
private AppWindow m_AppWindow;
public MainWindow()
{
this.InitializeComponent();
m_AppWindow = GetAppWindowForCurrentWindow();
m_AppWindow.Title = "App title";
}
private AppWindow GetAppWindowForCurrentWindow()
{
IntPtr hWnd = WindowNative.GetWindowHandle(this);
WindowId wndId = Win32Interop.GetWindowIdFromWindow(hWnd);
return AppWindow.GetFromWindowId(wndId);
}
Colors
Pokud chcete přizpůsobit výchozí barvy záhlaví nebo změnit výchozí ikonu okna, budete muset použít rozhraní APPWindow API nebo se rozhodnout plně přizpůsobit záhlaví.
Tento příklad ukazuje, jak získat instanci AppWindowTitleBar a nastavit její vlastnosti barvy.
Important
Přizpůsobení barev se ignoruje, když se aplikace spustí na Windows 10.
// Assumes "this" is a XAML Window. In projects that don't use
// WinUI 1.3 or later, use interop APIs to get the AppWindow.
AppWindow m_AppWindow = this.AppWindow;
private bool SetTitleBarColors()
{
// Check to see if customization is supported.
// The method returns true on Windows 10 since Windows App SDK 1.2,
// and on all versions of Windows App SDK on Windows 11.
if (AppWindowTitleBar.IsCustomizationSupported())
{
AppWindowTitleBar m_TitleBar = m_AppWindow.TitleBar;
// Set active window colors.
// Note: No effect when app is running on Windows 10
// because color customization is not supported.
m_TitleBar.ForegroundColor = Colors.White;
m_TitleBar.BackgroundColor = Colors.Green;
m_TitleBar.ButtonForegroundColor = Colors.White;
m_TitleBar.ButtonBackgroundColor = Colors.SeaGreen;
m_TitleBar.ButtonHoverForegroundColor = Colors.Gainsboro;
m_TitleBar.ButtonHoverBackgroundColor = Colors.DarkSeaGreen;
m_TitleBar.ButtonPressedForegroundColor = Colors.Gray;
m_TitleBar.ButtonPressedBackgroundColor = Colors.LightGreen;
// Set inactive window colors.
// Note: No effect when app is running on Windows 10
// because color customization is not supported.
m_TitleBar.InactiveForegroundColor = Colors.Gainsboro;
m_TitleBar.InactiveBackgroundColor = Colors.SeaGreen;
m_TitleBar.ButtonInactiveForegroundColor = Colors.Gainsboro;
m_TitleBar.ButtonInactiveBackgroundColor = Colors.SeaGreen;
return true;
}
return false;
}
Při nastavování barev záhlaví je potřeba vědět několik věcí:
- Barva pozadí tlačítka se nepoužije ve stavech přetažení myší a stisknutí tlačítka zavřít. Tlačítko Zavřít vždy používá pro tyto stavy barvu definovanou systémem.
- Nastavením vlastnosti barvy
nullse obnoví na výchozí systémovou barvu. - Nemůžete nastavit průhledné barvy. Alfa kanál barvy se ignoruje.
Windows dává uživateli možnost použít vybranou barvu zvýraznění na záhlaví. Pokud nastavíte barvu záhlaví, doporučujeme explicitně nastavit všechny barvy. Tím se zajistí, že neexistují žádné nezamýšlené kombinace barev, ke kterým dochází kvůli uživatelsky definovaným nastavením barev.
Ikona a systémová nabídka
Ikonu systému můžete skrýt nebo ji nahradit vlastní ikonou. Ikona systému zobrazuje systémovou nabídku, když jednou kliknete pravým tlačítkem nebo klepnete. Zavře okno při dvojitém kliknutí či poklepání.
Pokud chcete zobrazit nebo skrýt ikonu systému a související chování, nastavte vlastnost IconShowOptions záhlaví .
m_TitleBar.IconShowOptions = IconShowOptions.HideIconAndSystemMenu;
Pokud chcete použít vlastní ikonu okna, zavolejte některou z metod AppWindow.SetIcon pro nastavení nové ikony.
SetIcon(String)Metoda SetIcon(String) v současné době funguje pouze s .ico soubory. Řetězec, který této metodě předáte, je plně kvalifikovaná cesta k .ico souboru.
m_AppWindow.SetIcon("iconPath/iconName.ico");SetIcon(IconId)Pokud už máte popisovač ikony (
HICON) z některé z funkcí ikony, jako je CreateIcon, můžete k získání IconId použít rozhraní API zprostředkovatele GetIconFromIcon. Pak můžete předatIconIdmetodě SetIcon(IconId) a nastavit ikonu okna.m_AppWindow.SetIcon(iconId));
Úplné přizpůsobení
Když se přihlásíte k přizpůsobení celého záhlaví, oblast klienta aplikace se rozšíří tak, aby pokrývala celé okno, včetně oblasti záhlaví. Zodpovídáte za kreslení a zpracování vstupu pro celé okno s výjimkou tlačítek titulků, které okno stále poskytuje.
Chcete-li skrýt záhlaví systému a rozšířit obsah do oblasti záhlaví, nastavte vlastnost, která rozšiřuje obsah aplikace do oblasti záhlaví na true. V aplikaci XAML můžete tuto vlastnost nastavit v metodě vaší aplikace OnLaunched (App.xaml.cs) nebo na první stránce vaší aplikace.
Tip
Pokud chcete zobrazit veškerý kód najednou, podívejte se na část Příklad úplného přizpůsobení.
Tento příklad ukazuje, jak nastavit Window.ExtendsContentIntoTitleBar vlastnost true.
public MainWindow()
{
this.InitializeComponent();
// Hide system title bar.
ExtendsContentIntoTitleBar = true;
}
Caution
ExtendsContentIntoTitleBar zobrazuje se v XAML IntelliSense pro Window, ale pokud je nastaven v XAML, dojde k chybě. Tuto vlastnost nastavte v kódu.
Tento příklad ukazuje, jak získat AppWindowTitleBar a nastavit AppWindowTitleBar.ExtendsContentIntoTitleBar vlastnost true. Tento příklad ukazuje, jak pomocí rozhraní API pro interoperabilitu získat AppWindow, což je potřeba, pokud vaše aplikace nepoužívá WinUI 1.3 nebo novější.
using Microsoft.UI; // Needed for WindowId.
using Microsoft.UI.Windowing; // Needed for AppWindow.
using WinRT.Interop; // Needed for XAML/HWND interop.
private AppWindow m_AppWindow;
public MainWindow()
{
this.InitializeComponent();
m_AppWindow = GetAppWindowForCurrentWindow();
var titleBar = m_AppWindow.TitleBar;
// Hide system title bar.
titleBar.ExtendsContentIntoTitleBar = true;
}
private AppWindow GetAppWindowForCurrentWindow()
{
IntPtr hWnd = WindowNative.GetWindowHandle(this);
WindowId wndId = Win32Interop.GetWindowIdFromWindow(hWnd);
return AppWindow.GetFromWindowId(wndId);
}
Obsah záhlaví a výchozí oblast přetažení
Když se aplikace rozšíří do oblasti záhlaví, zodpovídáte za definování a správu uživatelského rozhraní záhlaví. Obvykle to zahrnuje minimálně specifikaci textu nadpisu a oblasti přetažení. Oblast přetažení záhlaví definuje, kam uživatel může kliknout a přetáhnout okno. Uživatel může také kliknout pravým tlačítkem myši a zobrazit tak systémovou nabídku.
Další informace o přijatelném obsahu záhlaví a doporučených vzorcích uživatelského rozhraní naleznete v Návrhu záhlaví.
Tento příklad ukazuje XAML pro vlastní uživatelské rozhraní záhlaví bez interaktivního obsahu.
<Grid x:Name="AppTitleBar"
Height="32">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
<Image x:Name="TitleBarIcon" Source="ms-appx:///Assets/StoreLogo.png"
Grid.Column="1"
HorizontalAlignment="Left"
Width="16" Height="16"
Margin="8,0,0,0"/>
<TextBlock x:Name="TitleBarTextBlock"
Text="App title"
Style="{StaticResource CaptionTextBlockStyle}"
Grid.Column="1"
VerticalAlignment="Center"
Margin="28,0,0,0"/>
</Grid>
Important
K rezervaci místa pro tlačítka titulků se používají LeftPaddingColumn a RightPaddingColumn. Hodnoty Width pro tyto sloupce se nastaví v kódu, který se zobrazí později. Kód a vysvětlení najdete v části Tlačítky titulků systému.
Aplikace XAML má zobrazovaný název nastavený v souboru Package.appxmanifest. Tuto hodnotu můžete získat a použít ji ve vlastním záhlaví takto.
TitleBarTextBlock.Text = AppInfo.Current.DisplayInfo.DisplayName;
Když obsah rozšíříte do oblasti záhlaví, systémový titulkový panel se skryje a vytvoří se výchozí AppWindowTitleBar, který poskytuje tlačítka titulu a oblast přetažení přes šířku obrazovky, shodně se systémovým titulkovým panelem. Pokud do záhlaví neumisťujete interaktivní obsah, můžete ponechat tuto výchozí oblast přetažení as-is. Pokud do záhlaví umístíte interaktivní obsah, musíte zadat oblasti, které jsou interaktivní, které probereme v další části.
Caution
Když definujete vlastní oblasti přetažení, nemusí být v horní části okna ve výchozí oblasti záhlaví; můžete definovat libovolnou část uživatelského rozhraní jako oblast přetažení. Umístění oblastí přetažení na různá místa ale může uživatelům ztížit jejich zjištění.
Interaktivní obsah
Interaktivní ovládací prvky, jako jsou tlačítka, nabídky nebo vyhledávací pole, můžete umístit do horní části aplikace, aby se zobrazovaly v záhlaví. Musíte ale určit, které oblasti jsou interaktivní, abyste zajistili, že interaktivní prvky přijímají uživatelský vstup a zároveň umožňují uživatelům přesouvat okno.
Když do oblasti záhlaví přidáte interaktivní obsah, musíte použít třídu InputNonClientPointerSource k určení oblastí, ve kterých se vstup předává interaktivnímu ovládacímu prvku, namísto zpracování záhlavím. Chcete-li nastavit interaktivní oblasti, zavolejte metodu InputNonClientPointerSource.SetRegionRects. Tato metoda přebírá hodnotu, která určuje typ sady oblastí (v tomto případě Passthrough) a pole obdélníků, z nichž každá definuje Passthrough oblast. Když se změní velikost záhlaví, je potřeba přepočítat interaktivní oblasti tak, aby odpovídaly nové velikosti, a volat SetRegionRects s novými hodnotami.
Tento příklad ukazuje vlastní uživatelské rozhraní záhlaví s vyhledávacím polem a ovládacím prvku účtu PersonPicture. Ukazuje, jak vypočítat a nastavit interaktivní obdélníky pro tyto ovládací prvky tak, aby vstup byl předán do nich.
Tady je několik důležitých bodů, které byste si o tomto kódu mohli všimnout:
- Nastavte výšku mřížky
AppTitleBarna 48, abyste postupli podle pokynů k návrhu záhlaví interaktivního obsahu. - Nastavte preferredHeightOption tak, aby
Talltlačítka titulků byla stejná výška jako záhlaví. - Pokud chcete usnadnit změnu velikosti ovládacích prvků a výpočet oblastí, použijte
Grids více pojmenovanými sloupci pro rozložení. - Použijte hvězdičkovou (*) velikost pro sloupec, který obsahuje
MinWidth, aby se automaticky přizpůsobil velikosti okna. - Nastavte
MinWidthnaRightDragColumn, abyste si rezervovali malou oblast, která je vždy přetažitelná, i když změníte velikost okna. - Nastavte
ExtendsContentIntoTitleBarnatruev konstruktoru MainWindow. Pokud jej nastavíte v kódu, který se zavolá později, může se nejdříve zobrazit výchozí systémový titulkový pruh a poté být skryt. - Proveďte počáteční volání pro výpočet interaktivních oblastí po načtení elementu
AppTitleBar. Jinak neexistuje žádná záruka, že prvky použité pro výpočet budou mít správné hodnoty. - Aktualizujte interaktivní výpočty obdélníku až po změně velikosti prvku
AppTitleBar(AppTitleBar_SizeChanged). Pokud závisíte na události v okněChanged, nastanou situace (například maximalizace nebo minimalizace okna), kdy k události dojde dříve, než se změní velikostAppTitleBar, a výpočty budou vycházet z nesprávných hodnot. - Nastavte vlastní oblasti pro přetahování nebo interaktivní pouze po zaškrtnutí
ExtendsContentIntoTitleBar, abyste potvrdili, že se používá vlastní záhlaví.
<Grid x:Name="AppTitleBar"
Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition x:Name="IconColumn" Width="Auto"/>
<ColumnDefinition x:Name="TitleColumn" Width="Auto"/>
<ColumnDefinition x:Name="LeftDragColumn" Width="*"/>
<ColumnDefinition x:Name="SearchColumn" Width="4*" MinWidth="220"/>
<ColumnDefinition x:Name="RightDragColumn" Width="*" MinWidth="48"/>
<ColumnDefinition x:Name="AccountColumn" Width="Auto"/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
<Image x:Name="TitleBarIcon"
Source="ms-appx:///Assets/StoreLogo.png"
Grid.Column="1"
Width="16" Height="16"
Margin="8,0,4,0"/>
<TextBlock x:Name="TitleBarTextBlock"
Text="App title"
Style="{StaticResource CaptionTextBlockStyle}"
Grid.Column="2"
VerticalAlignment="Center">
</TextBlock>
<AutoSuggestBox x:Name="TitleBarSearchBox"
Grid.Column="4"
QueryIcon="Find"
PlaceholderText="Search"
VerticalAlignment="Center"
MaxWidth="600"/>
<PersonPicture x:Name="PersonPic"
Grid.Column="6"
Height="32" Margin="0,0,16,0"/>
</Grid>
Tento kód ukazuje, jak vypočítat a nastavit interaktivní oblasti, které odpovídají ovládacím prvkům AutoSuggestBox a PersonPicture .
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
// Assumes "this" is a XAML Window. In projects that don't use
// WinUI 1.3 or later, use interop APIs to get the AppWindow.
m_AppWindow = this.AppWindow;
AppTitleBar.Loaded += AppTitleBar_Loaded;
AppTitleBar.SizeChanged += AppTitleBar_SizeChanged;
ExtendsContentIntoTitleBar = true;
TitleBarTextBlock.Text = AppInfo.Current.DisplayInfo.DisplayName;
}
private void AppTitleBar_Loaded(object sender, RoutedEventArgs e)
{
if (ExtendsContentIntoTitleBar == true)
{
// Set the initial interactive regions.
SetRegionsForCustomTitleBar();
}
}
private void AppTitleBar_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ExtendsContentIntoTitleBar == true)
{
// Update interactive regions if the size of the window changes.
SetRegionsForCustomTitleBar();
}
}
private void SetRegionsForCustomTitleBar()
{
// Specify the interactive regions of the title bar.
double scaleAdjustment = AppTitleBar.XamlRoot.RasterizationScale;
RightPaddingColumn.Width = new GridLength(m_AppWindow.TitleBar.RightInset / scaleAdjustment);
LeftPaddingColumn.Width = new GridLength(m_AppWindow.TitleBar.LeftInset / scaleAdjustment);
GeneralTransform transform = TitleBarSearchBox.TransformToVisual(null);
Rect bounds = transform.TransformBounds(new Rect(0, 0,
TitleBarSearchBox.ActualWidth,
TitleBarSearchBox.ActualHeight));
Windows.Graphics.RectInt32 SearchBoxRect = GetRect(bounds, scaleAdjustment);
transform = PersonPic.TransformToVisual(null);
bounds = transform.TransformBounds(new Rect(0, 0,
PersonPic.ActualWidth,
PersonPic.ActualHeight));
Windows.Graphics.RectInt32 PersonPicRect = GetRect(bounds, scaleAdjustment);
var rectArray = new Windows.Graphics.RectInt32[] { SearchBoxRect, PersonPicRect };
InputNonClientPointerSource nonClientInputSrc =
InputNonClientPointerSource.GetForWindowId(this.AppWindow.Id);
nonClientInputSrc.SetRegionRects(NonClientRegionKind.Passthrough, rectArray);
}
private Windows.Graphics.RectInt32 GetRect(Rect bounds, double scale)
{
return new Windows.Graphics.RectInt32(
_X: (int)Math.Round(bounds.X * scale),
_Y: (int)Math.Round(bounds.Y * scale),
_Width: (int)Math.Round(bounds.Width * scale),
_Height: (int)Math.Round(bounds.Height * scale)
);
}
}
Warning
AppWindow používá fyzické pixely pro kompatibilitu s architekturami uživatelského rozhraní, které nepoužívají logické souřadnice. Pokud používáte WPF nebo WinUI, RightInset, LeftInset a hodnoty použité k výpočtu oblastí je potřeba upravit, pokud měřítko zobrazení není 100%. V tomto příkladu získáme hodnotu scaleAdjustment pro nastavení měřítka zobrazení.
- Pro WinUI použijte vlastnost XamlRoot.RasterizationScale pro získání úpravy škálování.
- Pro WPF můžete zpracovat událost Window.DpiChanged a získat hodnotu NewDpi a vypočítat úpravu měřítka.
Tlačítka titulků systému
Systém si vyhrazuje levý horní nebo pravý horní roh okna aplikace pro tlačítka titulků systému (minimalizovat, maximalizovat/obnovit, zavřít). Systém si zachová kontrolu nad oblastí tlačítek titulků a zaručuje, že minimální funkčnost je poskytována pro přetahování, minimalizaci, maximalizaci a zavření okna. Systém kreslí tlačítko Zavřít v pravém horním rohu pro jazyky s pořadím zleva doprava a v levém horním rohu pro jazyky se zprava doleva.
Obsah můžete nakreslit pod oblastí ovládacího prvku titulků, například pozadí aplikace, ale neměli byste vložit žádné uživatelské rozhraní, se kterým očekáváte, že uživatel bude moct pracovat. Neobdrží žádný vstup, protože vstup ovládacích prvků titulků zpracovává systém.
Tyto řádky z předchozího příkladu ukazují odsazovací sloupce v XAML, který definuje záhlaví. Použití odsazení sloupců místo okrajů zajišťuje, že pozadí vykreslí oblast pod ovládacími tlačítky titulku (pro průhledná tlačítka). Použití odsazovacích sloupců zprava i zleva zajistí, že se titulek bude v rozloženích zprava doleva i zleva doprava chovat správně.
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
Dimenze a umístění oblasti ovládacího prvku titulku jsou komunikovány třídou AppWindowTitleBar , abyste ji mohli zohlednit v rozložení uživatelského rozhraní záhlaví. Šířka rezervované oblasti na každé straně je dána vlastnostmi LeftInset nebo RightInset a její výška je uvedena vlastností Height .
Takto se určuje šířka sloupců odsazení, když se vypočítávají a nastavují oblasti přetažení.
RightPaddingColumn.Width =
new GridLength(m_AppWindow.TitleBar.RightInset / scaleAdjustment);
LeftPaddingColumn.Width =
new GridLength(m_AppWindow.TitleBar.LeftInset / scaleAdjustment);
Important
Důležité informace najdete v části Interaktivní obsah o tom, jak škálování zobrazení ovlivňuje tyto hodnoty.
Podpora horního záhlaví pro vlastní záhlaví
Když do záhlaví přidáte interaktivní obsah, jako je vyhledávací pole nebo obrázek osoby, doporučujeme zvětšit výšku záhlaví, abyste těmto prvkům poskytli větší prostor. Vyšší záhlaví také usnadňuje manipulaci s dotykovým ovládáním.
Vlastnost AppWindowTitleBar.PreferredHeightOption umožňuje zvýšit výšku záhlaví ze standardní výšky, což je výchozí hodnota, na výšku vyšší. Když vyberete režim záhlaví Tall, tlačítka titulkové lišty, která systém nakreslí jako překrytí v oblasti klienta, se zobrazí vyšší, s glyfy pro minimalizaci/maximalizaci/zavření umístěnými do středu. Pokud jste nezadali oblast přetažení, systém nakreslí oblast, která rozšíří šířku okna a výšku určenou hodnotou PreferredHeightOption, kterou nastavíte.
Tento příklad ukazuje, jak můžete nastavit vlastnost PreferredHeightOption.
// A taller title bar is only supported when drawing a fully custom title bar.
if (ExtendsContentIntoTitleBar == true)
{
m_AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall;
}
Caution
Vlastnost AppWindowTitleBar.ExtendsContentIntoTitleBar musí být true před nastavením PreferredHeightOption vlastnosti. Pokud se pokusíte nastavit PreferredHeightOption, když je ExtendsContentIntoTitleBarfalse, vyvolá se výjimka.
Barva a průhlednost tlačítek titulků
Když rozšíříte obsah aplikace do oblasti záhlaví, můžete nastavit průhledné pozadí tlačítek v záhlaví okna, aby se zobrazilo pozadí aplikace. Pozadí obvykle nastavíte na Colors.Transparent pro úplnou průhlednost. Pro částečnou průhlednost nastavte alfa kanál pro barvu , na kterou nastavíte vlastnost.
Tyto vlastnosti záhlaví můžou být průhledné:
- ButtonBackgroundColor
- ButtonHoverBackgroundColor
- ButtonPressedBackgroundColor
- ButtonInactiveBackgroundColor
Všechny ostatní vlastnosti barvy budou i nadále ignorovat alfa kanál. Pokud je ExtendsContentIntoTitleBar nastavena na false, alfa kanál je vždy ignorován pro všechny vlastnosti barvy AppWindowTitleBar.
Barva pozadí tlačítka se nepoužije u Zavřít při přejetí myší a stisknutí stavy. Tlačítko Zavřít vždy používá pro tyto stavy barvu definovanou systémem.
Tip
Mica je nádherný materiál, který pomáhá odlišit okno, které je v popředí. Doporučujeme ho používat jako pozadí pro dlouhodobá okna v Windows 11. Pokud jste v klientské oblasti okna použili efekt Mica, můžete ho rozšířit do oblasti záhlaví a zprůhlednit ovládací tlačítka, aby mohl efekt Mica prosvítat. Další informace najdete v materiálech Mica .
Ztlumit panel titulku, když je okno neaktivní
Měli byste to zviditelnit, když je okno aktivní nebo neaktivní. Minimálně byste měli změnit barvu textu, ikon a tlačítek v záhlaví.
V případě aplikací XAML zpracujte událost Window.Activated , abyste zjistili stav aktivace okna, a podle potřeby aktualizujte uživatelské rozhraní záhlaví.
public MainWindow()
{
...
Activated += MainWindow_Activated;
}
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
if (args.WindowActivationState == WindowActivationState.Deactivated)
{
TitleBarTextBlock.Foreground =
(SolidColorBrush)App.Current.Resources["WindowCaptionForegroundDisabled"];
}
else
{
TitleBarTextBlock.Foreground =
(SolidColorBrush)App.Current.Resources["WindowCaptionForeground"];
}
}
V případě jiných architektur uživatelského rozhraní zpracujte událost, která určuje stav aktivace okna, a podle potřeby aktualizujte uživatelské rozhraní záhlaví. Způsob určení stavu okna závisí na rozhraní uživatelského rozhraní, které používáte pro vaši aplikaci.
- Win32: Poslouchejte zprávu WM_ACTIVATE a odpovězte na ni.
- WPF: Zpracovat Window.Activated, Window.Deactivated.
- WinForms: Zpracovat Form.Activated, Form.Deactivate.
Resetování záhlaví
Chcete-li vrátit nebo přepnout na systémové záhlaví, když je aplikace běžící, můžete zavolat AppWindowTitleBar.ResetToDefault.
m_AppWindow.TitleBar.ResetToDefault();
U aplikací XAML můžete také resetovat záhlaví takto:
- Zavolejte SetTitleBar pro přepnutí na nový titulkový prvek, zatímco aplikace běží.
- Pro resetování na výchozí oblasti přetahování
SetTitleBarpoužijte volánínulls parametremAppWindowTitleBar. - Zavolejte
SetTitleBarsnulljako parametrem a nastavte ExtendsContentIntoTitleBar nafalse, aby se obnovilo výchozí systémové záhlaví.
Zobrazení a skrytí záhlaví
Pokud do aplikace přidáte podporu režimu překrytí na celou obrazovku nebo kompaktní režimy, budete možná muset při přepínání mezi těmito režimy provést změny v záhlaví. Okno XAML neposkytuje žádná rozhraní API pro podporu režimu zobrazení na celé obrazovce; K tomu můžete použít rozhraní AppWindow API.
Když aplikace běží v režimu celé obrazovky , systém skryje ovládací tlačítka záhlaví a titulku. Můžete zpracovat událost AppWindow.Changed a ověřit vlastnost DidPresenterChange argumentů události, abyste zjistili, zda byste měli zobrazit, skrýt nebo změnit titulkový pruh jako reakci na novou prezentaci okna.
Tento příklad ukazuje, jak zpracovat Changed událost k zobrazení a skrytí AppTitleBar elementu z předchozích příkladů. Pokud je okno v kompaktním překryvném režimu, záhlaví se obnoví na výchozí záhlaví systému (nebo můžete zadat vlastní záhlaví optimalizované pro kompaktní překrytí).
public MainWindow()
{
this.InitializeComponent();
m_AppWindow = this.AppWindow;
m_AppWindow.Changed += AppWindow_Changed;
}
private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
if (args.DidPresenterChange)
{
switch (sender.Presenter.Kind)
{
case AppWindowPresenterKind.CompactOverlay:
// Compact overlay - hide custom title bar
// and use the default system title bar instead.
AppTitleBar.Visibility = Visibility.Collapsed;
sender.TitleBar.ResetToDefault();
break;
case AppWindowPresenterKind.FullScreen:
// Full screen - hide the custom title bar
// and the default system title bar.
AppTitleBar.Visibility = Visibility.Collapsed;
sender.TitleBar.ExtendsContentIntoTitleBar = true;
break;
case AppWindowPresenterKind.Overlapped:
// Normal - hide the system title bar
// and use the custom title bar instead.
AppTitleBar.Visibility = Visibility.Visible;
sender.TitleBar.ExtendsContentIntoTitleBar = true;
break;
default:
// Use the default system title bar.
sender.TitleBar.ResetToDefault();
break;
}
}
}
Note
Celá obrazovka a kompaktní překrytí lze zadat jenom v případě, že je podporováno vaší aplikací. Další informace najdete v tématu Správa oken aplikací, FullScreenPresenter a CompactOverlayPresenter.
Co dělat a co nedělat
- Zviditelněte, když je okno aktivní nebo neaktivní. Minimálně změňte barvu textu, ikon a tlačítek v záhlaví.
- Definujte oblast přetažení podél horního okraje plátna aplikace. Porovnávání umístění systémových záhlaví usnadňuje uživatelům hledání.
- Definujte oblast přetažení, která odpovídá záhlaví vizuálu (pokud existuje) na plátně aplikace.
Příklad úplného přizpůsobení
Tento příklad ukazuje veškerý kód popsaný v části Úplné přizpůsobení.
<Window
x:Class="WinUI3_CustomTitleBar.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"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid x:Name="AppTitleBar"
Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition x:Name="IconColumn" Width="Auto"/>
<ColumnDefinition x:Name="TitleColumn" Width="Auto"/>
<ColumnDefinition x:Name="LeftDragColumn" Width="*"/>
<ColumnDefinition x:Name="SearchColumn" Width="4*" MinWidth="220"/>
<ColumnDefinition x:Name="RightDragColumn" Width="*" MinWidth="48"/>
<ColumnDefinition x:Name="AccountColumn" Width="Auto"/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
<Image x:Name="TitleBarIcon"
Source="ms-appx:///Assets/StoreLogo.png"
Grid.Column="1"
Width="16" Height="16"
Margin="8,0,4,0"/>
<TextBlock x:Name="TitleBarTextBlock"
Text="App title"
Style="{StaticResource CaptionTextBlockStyle}"
Grid.Column="2"
VerticalAlignment="Center">
</TextBlock>
<AutoSuggestBox x:Name="TitleBarSearchBox"
Grid.Column="4"
QueryIcon="Find"
PlaceholderText="Search"
VerticalAlignment="Center"
MaxWidth="600"/>
<PersonPicture x:Name="PersonPic"
Grid.Column="6"
Height="32" Margin="0,0,16,0"/>
</Grid>
<NavigationView Grid.Row="1"
IsBackButtonVisible="Collapsed"
IsSettingsVisible="False">
<StackPanel>
<TextBlock Text="Content"
Style="{ThemeResource TitleTextBlockStyle}"
Margin="32,0,0,0"/>
<StackPanel Grid.Row="1" VerticalAlignment="Center">
<Button Margin="4" x:Name="CompactoverlaytBtn"
Content="Enter CompactOverlay"
Click="SwitchPresenter"/>
<Button Margin="4" x:Name="FullscreenBtn"
Content="Enter FullScreen"
Click="SwitchPresenter"/>
<Button Margin="4" x:Name="OverlappedBtn"
Content="Revert to default (Overlapped)"
Click="SwitchPresenter"/>
</StackPanel>
</StackPanel>
</NavigationView>
</Grid>
</Window>
using Microsoft.UI.Input;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System;
using Windows.ApplicationModel;
using Rect = Windows.Foundation.Rect;
public sealed partial class MainWindow : Window
{
private AppWindow m_AppWindow;
public MainWindow()
{
this.InitializeComponent();
// Assumes "this" is a XAML Window. In projects that don't use
// WinUI 1.3 or later, use interop APIs to get the AppWindow.
m_AppWindow = this.AppWindow;
m_AppWindow.Changed += AppWindow_Changed;
Activated += MainWindow_Activated;
AppTitleBar.SizeChanged += AppTitleBar_SizeChanged;
AppTitleBar.Loaded += AppTitleBar_Loaded;
ExtendsContentIntoTitleBar = true;
if (ExtendsContentIntoTitleBar == true)
{
m_AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall;
}
TitleBarTextBlock.Text = AppInfo.Current.DisplayInfo.DisplayName;
}
private void AppTitleBar_Loaded(object sender, RoutedEventArgs e)
{
if (ExtendsContentIntoTitleBar == true)
{
// Set the initial interactive regions.
SetRegionsForCustomTitleBar();
}
}
private void AppTitleBar_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ExtendsContentIntoTitleBar == true)
{
// Update interactive regions if the size of the window changes.
SetRegionsForCustomTitleBar();
}
}
private void SetRegionsForCustomTitleBar()
{
// Specify the interactive regions of the title bar.
double scaleAdjustment = AppTitleBar.XamlRoot.RasterizationScale;
RightPaddingColumn.Width = new GridLength(m_AppWindow.TitleBar.RightInset / scaleAdjustment);
LeftPaddingColumn.Width = new GridLength(m_AppWindow.TitleBar.LeftInset / scaleAdjustment);
// Get the rectangle around the AutoSuggestBox control.
GeneralTransform transform = TitleBarSearchBox.TransformToVisual(null);
Rect bounds = transform.TransformBounds(new Rect(0, 0,
TitleBarSearchBox.ActualWidth,
TitleBarSearchBox.ActualHeight));
Windows.Graphics.RectInt32 SearchBoxRect = GetRect(bounds, scaleAdjustment);
// Get the rectangle around the PersonPicture control.
transform = PersonPic.TransformToVisual(null);
bounds = transform.TransformBounds(new Rect(0, 0,
PersonPic.ActualWidth,
PersonPic.ActualHeight));
Windows.Graphics.RectInt32 PersonPicRect = GetRect(bounds, scaleAdjustment);
var rectArray = new Windows.Graphics.RectInt32[] { SearchBoxRect, PersonPicRect };
InputNonClientPointerSource nonClientInputSrc =
InputNonClientPointerSource.GetForWindowId(this.AppWindow.Id);
nonClientInputSrc.SetRegionRects(NonClientRegionKind.Passthrough, rectArray);
}
private Windows.Graphics.RectInt32 GetRect(Rect bounds, double scale)
{
return new Windows.Graphics.RectInt32(
_X: (int)Math.Round(bounds.X * scale),
_Y: (int)Math.Round(bounds.Y * scale),
_Width: (int)Math.Round(bounds.Width * scale),
_Height: (int)Math.Round(bounds.Height * scale)
);
}
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
if (args.WindowActivationState == WindowActivationState.Deactivated)
{
TitleBarTextBlock.Foreground =
(SolidColorBrush)App.Current.Resources["WindowCaptionForegroundDisabled"];
}
else
{
TitleBarTextBlock.Foreground =
(SolidColorBrush)App.Current.Resources["WindowCaptionForeground"];
}
}
private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
if (args.DidPresenterChange)
{
switch (sender.Presenter.Kind)
{
case AppWindowPresenterKind.CompactOverlay:
// Compact overlay - hide custom title bar
// and use the default system title bar instead.
AppTitleBar.Visibility = Visibility.Collapsed;
sender.TitleBar.ResetToDefault();
break;
case AppWindowPresenterKind.FullScreen:
// Full screen - hide the custom title bar
// and the default system title bar.
AppTitleBar.Visibility = Visibility.Collapsed;
sender.TitleBar.ExtendsContentIntoTitleBar = true;
break;
case AppWindowPresenterKind.Overlapped:
// Normal - hide the system title bar
// and use the custom title bar instead.
AppTitleBar.Visibility = Visibility.Visible;
sender.TitleBar.ExtendsContentIntoTitleBar = true;
break;
default:
// Use the default system title bar.
sender.TitleBar.ResetToDefault();
break;
}
}
}
private void SwitchPresenter(object sender, RoutedEventArgs e)
{
if (AppWindow != null)
{
AppWindowPresenterKind newPresenterKind;
switch ((sender as Button).Name)
{
case "CompactoverlaytBtn":
newPresenterKind = AppWindowPresenterKind.CompactOverlay;
break;
case "FullscreenBtn":
newPresenterKind = AppWindowPresenterKind.FullScreen;
break;
case "OverlappedBtn":
newPresenterKind = AppWindowPresenterKind.Overlapped;
break;
default:
newPresenterKind = AppWindowPresenterKind.Default;
break;
}
// If the same presenter button was pressed as the
// mode we're in, toggle the window back to Default.
if (newPresenterKind == AppWindow.Presenter.Kind)
{
AppWindow.SetPresenter(AppWindowPresenterKind.Default);
}
else
{
// Else request a presenter of the selected kind
// to be created and applied to the window.
AppWindow.SetPresenter(newPresenterKind);
}
}
}
}
Související články
Windows developer