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í záhlaví, přijatelného obsahu oblasti záhlaví a doporučených vzorů uživatelského rozhraní najdete v článku návrhu záhlaví aplikace.
Important
Tento článek ukazuje, jak přizpůsobit záhlaví aplikací, které používají sadu Windows App SDK, a to buď s WinUI 3, nebo bez. Informace o aplikacích, které používají UWP a WinUI 2, najdete v tématu přizpůsobení záhlaví pro UWP.
Important
Do sady Windows App SDK 1.7 byl přidán nový ovládací prvek Záhlaví . Zjednodušuje proces přizpůsobení záhlaví.
- Platí pro: Windows App SDK, desktopové aplikace WinUI 3
- 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
Funkcionalita oken v sadě Windows App SDK je realizována prostřednictvím třídy Microsoft.UI.Windowing.AppWindow, která je založena na modelu Win32 HWND. 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 oken ve WinUI 3 je prostřednictvím třídy Microsoft.UI.Xaml.Window , která je také založená na modelu HwND win32. Pro aplikace XAML, které používají WinUI 3, poskytují rozhraní API okna XAML jednodušší způsob přizpůsobení záhlaví a v případě potřeby vám umožní přístup k rozhraním AppWindow API.
Jak pracovat s AppWindow
Rozhraní AppWindow API můžete použít s libovolnou architekturou uživatelského rozhraní, kterou sada Windows App SDK podporuje – Win32, WPF, WinForms nebo WinUI 3 – a můžete je postupně používat pouze pomocí potřebných rozhraní API.
Pokud jako architekturu uživatelského rozhraní vaší aplikace použijete WinUI 3 XAML, budete k dispozici rozhraní API pro Windows i rozhraní AppWindow API. Počínaje windows App SDK 1.4 používají okno XAML a AppWindow stejný objekt AppWindowTitleBar 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 přístup k rozhraním API pro přizpůsobení záhlaví.
Pokud chcete získat přístup k dalším funkcím záhlaví, můžete použít rozhraní APPWindow API z okna XAML takto: AppWindow.TitleBar.ForegroundColor = Colors.White;.
Pokud nepoužíváte WinUI 3 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ématu Správa oken aplikací – architektura uživatelského rozhraní a interoperability HWND a ukázková galerie oken .
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. Pokud vaše aplikace nepoužívá WinUI 3 ve verzi 1.3 nebo novější, tento příklad ukazuje, jak získat AppWindow pomocí rozhraní API pro interoperabilitu.
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ž aplikace běží ve Windows 10.
// Assumes "this" is a XAML Window. In projects that don't use
// WinUI 3 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 na tlačítko zavřít najetí myší a stisknuté stavy. 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 v případě, že vaše aplikace nepoužívá WinUI 3 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ý záhlaví se skryje a vytvoří se výchozí panel AppWindowTitleBar , který poskytuje tlačítka titulků a oblast přetažení přes šířku obrazovky shodný se systémovým záhlavím. 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 InputNonClientPointerSource třídy k určení oblastí, ve kterých se vstup předává interaktivnímu ovládacímu prvku, a nikoli zpracovávat záhlavím. Chcete-li nastavit interaktivní oblasti, zavolejte InputNonClientPointerSource.SetRegionRects metoda. 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í. - U sloupce, který obsahuje
AutoSuggestBoxvelikost hvězdičky (*), použijte velikostMinWidthhvězdičky (*), aby se automaticky změnila velikost 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 3 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 3, RightInset, LeftInseta 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 3 použijte XamlRoot.RasterizationScale vlastnost získat úpravu měřítka.
- U WPF můžete zpracovat událost Window.DpiChanged , abyste získali hodnotu NewDpi a vypočítali ú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 tlačítka Zavřít a stisknete 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 fokus. Doporučujeme ho používat jako pozadí pro dlouhodobá okna ve 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: Handle Window.Activated, Window.Deactivated.
- WinForms: Handle Form.Activated, Form.Deactivate.
Resetování záhlaví
Pokud chcete obnovit nebo přepnout na záhlaví systému, když je aplikace spuštěná, můžete volat AppWindowTitleBar.ResetToDefault.
m_AppWindow.TitleBar.ResetToDefault();
U aplikací XAML můžete také resetovat záhlaví takto:
- Volání SetTitleBar pro přepnutí na nový prvek záhlaví, když je aplikace spuštěná.
- Pro resetování na výchozí oblasti přetahování
SetTitleBarpoužijte volánínulls parametremAppWindowTitleBar. - Voláním
SetTitleBarjako parametremnulla nastavením ExtendsContentIntoTitleBar se vrátíte nafalsevý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 AppWindow.Changed událost a zkontrolovat args DidPresenterChange vlastnost určit, zda byste měli zobrazit, skrýt nebo změnit záhlaví v 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
Režimy překrytí na celé obrazovce a komprimované vrstvy se dají zadat jenom v případě, že je vaše aplikace podporovaná. 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 3 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