Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Windows biedt een standaardtitelbalk voor elk venster en stelt u in staat om het aan te passen aan de persoonlijkheid van uw app. De standaardtitelbalk bevat enkele standaardonderdelen en kernfunctionaliteit, zoals het slepen en wijzigen van het formaat van het venster.
Zie het titelbalk ontwerpartikel voor hulp bij het aanpassen van de titelbalk van uw app, acceptabele inhoud van het titelbalkgebied en aanbevolen ui-patronen.
Belangrijk
In dit artikel wordt beschreven hoe u de titelbalk kunt aanpassen voor apps die gebruikmaken van de Windows App SDK, met of zonder WinUI 3. Zie Titelbalk aanpassen voor UWP voor apps die gebruikmaken van UWP en WinUI 2.
- van toepassing op: Windows App SDK, WinUI 3-desktop-apps
- Belangrijke API's: eigenschap AppWindow.TitleBar, AppWindowTitleBar-klasse, AppWindow-klasse, Microsoft.UI.Xaml.Window-klasse, Window.ExtendsContentIntoTitleBar-eigenschap, methode Window.SetTitleBar
Onderdelen van titelbalk
In deze lijst worden de onderdelen van de standaardtitelbalk beschreven.
- Rechthoek met titelbalk
- Titeltekst
- Systeempictogram
- Systeemmenu - geopend door op het app-pictogram te klikken of met de rechtermuisknop op de titelbalk te klikken
- Besturingselementen voor ondertiteling
- Knop Minimaliseren
- Knop Maximaliseren/Herstellen
- Knop Sluiten
Vensterbeheer
Vensterfunctionaliteit in de Windows App SDK- wordt uitgevoerd via de klasse Microsoft.UI.Windowing.AppWindow, die is gebaseerd op het Win32 HWND-model. Er is een 1:1-toewijzing tussen een AppWindow en een HWND op het hoogste niveau in uw app. AppWindow en de bijbehorende klassen bieden API's waarmee u veel aspecten van de vensters op het hoogste niveau van uw app kunt beheren, waaronder het aanpassen van de titelbalk. U kunt de standaardtitelbalk wijzigen die Windows biedt, zodat deze wordt gecombineerd met de rest van uw gebruikersinterface, of uw app-canvas uitbreiden naar het titelbalkgebied en uw eigen titelbalkinhoud opgeven.
Vensterfunctionaliteit in WinUI 3 is via de klasse Microsoft.UI.Xaml.Window, die ook is gebaseerd op het Win32 HWND-model. Voor XAML-apps die gebruikmaken van WinUI 3, bieden XAML-venster-API's een eenvoudigere manier om de titelbalk aan te passen, terwijl u de AppWindow-API's nog steeds kunt openen wanneer dat nodig is.
Werken met AppWindow
U kunt AppWindow-API's gebruiken met elk UI-framework dat door de Windows App SDK wordt ondersteund: Win32, WPF, WinForms of WinUI 3. U kunt ze stapsgewijs gebruiken met alleen de API's die u nodig hebt.
Als u WinUI 3 XAML als ui-framework van uw app gebruikt, zijn zowel de Window- als de AppWindow API's beschikbaar voor u. Vanaf Windows App SDK 1.4 gebruiken het XAML-venster en AppWindow hetzelfde AppWindowTitleBar object voor het aanpassen van de titelbalk. Gebruik de eigenschap Window.AppWindow om een AppWindow-object op te halen uit een bestaand XAML-venster. Met dit AppWindow-object hebt u toegang tot de api's voor het aanpassen van de titelbalk.
Voor toegang tot extra functies van de titelbalk kunt u de AppWindow-API's uit uw XAML-venster als volgt gebruiken: AppWindow.TitleBar.ForegroundColor = Colors.White;
.
Als u geen WinUI 3 1.3 of hoger gebruikt, gebruikt u interop-API's om de AppWindow op te halen en de AppWindow-API's te gebruiken om de titelbalk aan te passen. Zie voor meer informatie over de interop-API's App-vensters beheren - UI-framework en HWND-interop en het venstergalerie voorbeeld.
Hoeveel u de titelbalk kunt aanpassen
Er zijn twee aanpassingsniveaus die u kunt toepassen op de titelbalk: kleine wijzigingen toepassen op de standaardtitelbalk of uw app-canvas uitbreiden naar het titelbalkgebied en volledig aangepaste inhoud bieden.
Eenvoudig
Voor eenvoudige aanpassingen, zoals het wijzigen van de titelbalkkleur, kunt u eigenschappen instellen op het object AppWindowTitleBar om de kleuren op te geven die u wilt gebruiken voor titelbalkelementen. In dit geval behoudt het systeem de verantwoordelijkheid voor alle andere aspecten van de titelbalk, zoals het tekenen van de app-titel en het definiëren van sleepgebieden.
Vol
U kunt de standaardtitelbalk van het systeem verbergen en vervangen door uw eigen aangepaste inhoud. U kunt bijvoorbeeld tekst, een zoekvak of aangepaste menu's in het titelbalkgebied plaatsen. U moet deze optie ook gebruiken om een materiaal uit te breiden achtergrond, zoals Mica, in het titelbalkgebied.
Wanneer u voor volledige aanpassing kiest, bent u verantwoordelijk voor het plaatsen van inhoud in het titelbalkgebied en kunt u uw eigen sleepregio's definiëren. De besturingselementen voor bijschriften (knoppen Sluiten, Minimaliseren en Maximaliseren) zijn nog steeds beschikbaar en verwerkt door het systeem, maar elementen zoals de titel van de app zijn niet beschikbaar. U moet deze elementen zelf maken als dat nodig is voor uw app.
Eenvoudige aanpassing
Als u alleen de titel, kleuren of het pictogram van de titelbalk wilt aanpassen, kunt u eigenschappen instellen op het titelbalkobject voor uw app-venster.
Titel
Standaard wordt op de titelbalk het app-type weergegeven als de titel van het venster (bijvoorbeeld 'WinUI Desktop'). U moet de titel van het venster bijwerken om een zinvolle weergavenaam voor uw app weer te geven.
Een XAML-app heeft een weergavenaam die is ingesteld in het Package.appxmanifest
-bestand. U kunt deze waarde ophalen en deze gebruiken om de eigenschap Title
als volgt in te stellen.
Title = AppInfo.Current.DisplayInfo.DisplayName;
Als u de titel van het venster wilt wijzigen, stelt u de eigenschap Window.Title in op een tekstwaarde met één regel, zoals hier wordt weergegeven.
<Window
...
Title="App title">
...
</Window>
public MainWindow()
{
InitializeComponent();
Title = "App title";
}
Als u de titel van het venster wilt wijzigen met behulp van AppWindow-API's, stelt u de eigenschap AppWindow.Title in op een tekstwaarde met één regel, zoals hier wordt weergegeven. In dit voorbeeld ziet u hoe u interop-API's gebruikt om de AppWindow op te halen, wat nodig is als uw app geen gebruikmaakt van WinUI 3 1.3 of hoger.
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);
}
Kleuren
Als u de standaardkleuren van de titelbalk wilt aanpassen of het standaardvensterpictogram wilt wijzigen, moet u de AppWindow-API's gebruiken of ervoor kiezen om uw titelbalk volledig aan te passen.
In dit voorbeeld wordt getoond hoe u een exemplaar van AppWindowTitleBar verkrijgt en de kleureigenschappen instelt.
Belangrijk
Kleuraanpassing wordt genegeerd wanneer de app wordt uitgevoerd in 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;
}
Er zijn enkele dingen waar u rekening mee moet houden bij het instellen van titelbalkkleuren:
- De achtergrondkleur van de knop wordt niet toegepast op de sluitknop hover en ingedrukt toestanden. De knop Sluiten gebruikt altijd de door het systeem gedefinieerde kleur voor deze statussen.
- Als u een kleureigenschap instelt op
null
wordt deze opnieuw ingesteld op de standaardsysteemkleur. - U kunt geen transparante kleuren instellen. Het alfakanaal van de kleur wordt genegeerd.
Windows biedt een gebruiker de mogelijkheid om de geselecteerde accentkleur toe te passen op de titelbalk. Als u een titelbalkkleur instelt, wordt u aangeraden alle kleuren expliciet in te stellen. Dit zorgt ervoor dat er geen onbedoelde kleurcombinaties zijn die optreden vanwege door de gebruiker gedefinieerde kleurinstellingen.
Pictogram- en systeemmenu
U kunt het systeempictogram verbergen of vervangen door een aangepast pictogram. Het systeempictogram toont het systeemmenu wanneer er eenmaal met de rechtermuisknop op is geklikt of getikt. Het venster wordt gesloten wanneer u dubbelklikt/tikt.
Als u het systeempictogram en het bijbehorende gedrag wilt weergeven of verbergen, stelt u de titelbalk in IconShowOptions-eigenschap.
m_TitleBar.IconShowOptions = IconShowOptions.HideIconAndSystemMenu;
Als u een aangepast vensterpictogram wilt gebruiken, roept u een van de AppWindow.SetIcon methoden aan om het nieuwe pictogram in te stellen.
SetIcon(String)
De methode SetIcon(String) werkt momenteel alleen met .ico bestanden. De tekenreeks die u aan deze methode doorgeeft, is het volledig gekwalificeerde pad naar het .ico-bestand.
m_AppWindow.SetIcon("iconPath/iconName.ico");
SetIcon(IconId)
Als u al een greep hebt naar een pictogram (
HICON
) van een van de Icon-functies zoals CreateIcon, kunt u de GetIconIdFromIcon interop-API gebruiken om een IconId-op te halen. Vervolgens kunt u deIconId
doorgeven aan de SetIcon(IconId) methode om het vensterpictogram in te stellen.m_AppWindow.SetIcon(iconId));
Volledige aanpassing
Wanneer u zich aanmeldt voor het aanpassen van de volledige titelbalk, wordt het clientgebied van uw app uitgebreid voor het hele venster, inclusief het titelbalkgebied. U bent verantwoordelijk voor het tekenen en verwerken van invoer voor het hele venster, behalve de bijschriftknoppen, die nog steeds door het venster worden geleverd.
Als u de titelbalk van het systeem wilt verbergen en uw inhoud wilt uitbreiden naar het titelbalkgebied, stelt u de eigenschap in waarmee app-inhoud in het titelbalkgebied wordt uitgebreid naar true
. In een XAML-app kan deze eigenschap worden ingesteld in de OnLaunched
methode (App.xaml.cs) van uw app of op de eerste pagina van uw app.
Aanbeveling
Zie het voorbeeld van volledige personalisatie sectie voor een overzicht van alle code.
In dit voorbeeld ziet u hoe u de eigenschap Window.ExtendsContentIntoTitleBar instelt op true
.
public MainWindow()
{
this.InitializeComponent();
// Hide system title bar.
ExtendsContentIntoTitleBar = true;
}
Voorzichtigheid
ExtendsContentIntoTitleBar
wordt weergegeven in de XAML IntelliSense voor Window
, maar als u deze instelt in XAML, treedt er een fout op. Stel deze eigenschap in plaats daarvan in code in.
In dit voorbeeld ziet u hoe u de eigenschap AppWindowTitleBar en de eigenschap AppWindowTitleBar.ExtendsContentIntoTitle Bar instelt op true
. In dit voorbeeld ziet u hoe u interop-API's gebruikt om de AppWindow op te halen. Dit is nodig als uw app geen WinUI 3 1.3 of hoger gebruikt.
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);
}
Inhoud van de titelbalk en het standaard sleepgebied
Wanneer uw app wordt uitgebreid tot het titelbalkgebied, bent u verantwoordelijk voor het definiëren en beheren van de gebruikersinterface voor de titelbalk. Dit omvat doorgaans minimaal het opgeven van titeltekst en het sleepgebied. Het sleepgebied van de titelbalk bepaalt waar de gebruiker kan klikken en slepen om het venster te verplaatsen. Hier kan de gebruiker ook met de rechtermuisknop klikken om het systeemmenu weer te geven.
Zie Ontwerp van de titelbalkvoor meer informatie over acceptabele inhoud van de titelbalk en aanbevolen ui-patronen.
In dit voorbeeld ziet u de XAML voor een aangepaste titelbalk zonder interactieve inhoud.
<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>
Belangrijk
De LeftPaddingColumn
en RightPaddingColumn
worden gebruikt om ruimte te reserveren voor de bijschriftknoppen. De Width
waarden voor deze kolommen worden ingesteld in code, die later wordt weergegeven. Zie de sectie Systeembijschriftknoppen voor de code en uitleg.
Een XAML-app heeft een weergavenaam die is ingesteld in het bestand Package.appxmanifest. U kunt deze waarde ophalen en deze gebruiken in uw aangepaste titelbalk zoals deze.
TitleBarTextBlock.Text = AppInfo.Current.DisplayInfo.DisplayName;
Wanneer u uw inhoud uitbreidt naar het titelbalkgebied, wordt de systeemtitelbalk verborgen en wordt er een standaard AppWindowTitleBar gemaakt die ondertitelingsknoppen en een sleepgebied over de breedte van het scherm biedt, identiek aan de systeemtitelbalk. Als u geen interactieve inhoud op de titelbalk plaatst, kunt u deze standaardregio voor slepen as-islaten. Als u interactieve inhoud op de titelbalk plaatst, moet u de regio's opgeven die interactief zijn, die in de volgende sectie worden besproken.
Voorzichtigheid
Wanneer u aangepaste sleepregio's definieert, hoeven ze zich niet boven aan het venster te bevinden in het standaardgebied van de titelbalk; u kunt elk deel van uw gebruikersinterface definiëren als een sleepregio. Het plaatsen van sleepregio's op verschillende plaatsen kan het echter lastig maken voor uw gebruikers om ze te ontdekken.
Interactieve inhoud
U kunt interactieve besturingselementen, zoals knoppen, menu's of een zoekvak, in het bovenste gedeelte van de app plaatsen, zodat ze zich in de titelbalk bevinden. U moet echter opgeven welke regio's interactief zijn om ervoor te zorgen dat uw interactieve elementen gebruikersinvoer ontvangen terwijl gebruikers uw venster toch kunnen verplaatsen.
Wanneer u interactieve inhoud toevoegt in het titelbalkgebied, moet u de InputNonClientPointerSource-klasse klasse gebruiken om gebieden op te geven waar invoer wordt doorgegeven aan het interactieve besturingselement, in plaats van verwerkt door de titelbalk. Als u interactieve regio's wilt instellen, gebruikt u de InputNonClientPointerSource.SetRegionRects methode. Deze methode gebruikt een waarde die het type regio aangeeft dat wordt ingesteld (in dit geval Passthrough
) en een matrix met rechthoeken, die elk een Passthrough
regio definieert. Wanneer de grootte van de titelbalk verandert, moet u de interactieve regio's opnieuw berekenen zodat deze overeenkomen met de nieuwe grootte en SetRegionRects
aanroepen met de nieuwe waarden.
In dit voorbeeld ziet u een aangepaste titelbalkinterface met een zoekvak en een PersonPicture-accountbeheer. Het laat zien hoe u de interactieve rechthoeken voor deze besturingselementen kunt berekenen en instellen, zodat er invoer aan deze besturingselementen wordt doorgegeven.
Hier volgen enkele belangrijke punten die u moet opmerken over deze code:
- Stel de hoogte van het
AppTitleBar
raster in op 48 om de titelbalk te volgen ontwerprichtlijnen voor interactieve inhoud. - Stel PreferredHeightOption- in op
Tall
zodat de bijschriftknoppen dezelfde hoogte hebben als de titelbalk. - Gebruik een
Grid
met meerdere benoemde kolommen voor de lay-out om het formaat van besturingselementen aan te passen en regio's te berekenen. - Gebruik sterformaat (*) met
MinWidth
voor de kolom die deAutoSuggestBox
bevat, zodat de grootte automatisch wordt aangepast aan het venster. - Stel
MinWidth
opRightDragColumn
in om een klein gebied te reserveren dat altijd gesleept kan worden, zelfs wanneer het venster van grootte verandert. - Stel
ExtendsContentIntoTitleBar
in optrue
in de MainWindow-constructor. Als u deze instelt in code die later wordt aangeroepen, wordt de standaardtitelbalk van het systeem mogelijk eerst weergegeven en vervolgens verborgen. - Voer de eerste aanroep uit om interactieve regio's te berekenen nadat het
AppTitleBar
-element is geladen. Anders is er geen garantie dat de elementen die voor de berekening worden gebruikt, de juiste waarden hebben. - Werk de interactieve rechthoekberekeningen pas bij nadat het
AppTitleBar
element de grootte (AppTitleBar_SizeChanged
) heeft gewijzigd). Als u afhankelijk bent van het vensterChanged
gebeurtenis, zijn er situaties (zoals venster maximaliseren/minimaliseren) waarin de gebeurtenis plaatsvindt voordatAppTitleBar
wordt gewijzigd en de berekeningen onjuiste waarden gebruiken. - Stel uw aangepaste sleep-/interactieve gebieden alleen in nadat u
ExtendsContentIntoTitleBar
hebt gecontroleerd om te bevestigen dat er een aangepaste titelbalk wordt gebruikt.
<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>
Deze code laat zien hoe u de interactieve regio's kunt berekenen en instellen die overeenkomen met de besturingselementen AutoSuggestBox en 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)
);
}
}
Waarschuwing
AppWindow
fysieke pixels gebruikt voor compatibiliteit met UI-frameworks die geen logische coördinaten gebruiken. Als u WPF of WinUI 3 gebruikt, RightInset
, LeftInset
en de waarden die worden gebruikt om regio's te berekenen, moeten worden aangepast als de weergaveschaal niet 100%is. In dit voorbeeld krijgen we een scaleAdjustment
waarde om rekening te houden met de weergaveschaalinstelling.
- Voor WinUI 3 gebruikt u de eigenschap XamlRoot.RasterizationScale om de schaalaanpassing op te halen.
- Voor WPF kunt u de gebeurtenis Window.DpiChanged afhandelen om de waarde van de NewDpi- op te halen en de schaalaanpassing te berekenen.
Knoppen voor systeembijschrift
Het systeem behoudt zich de linkerbovenhoek of rechterbovenhoek van het app-venster voor de knoppen voor systeembijschriften (minimaliseren, maximaliseren/herstellen, sluiten). Het systeem behoudt de controle over het gebied van de bijschriftknop om te garanderen dat minimale functionaliteit wordt geboden voor slepen, minimaliseren, maximaliseren en sluiten van het venster. Voor talen van links naar rechts tekent het systeem de knop Sluiten in de rechterbovenhoek, en voor talen van rechts naar links tekent het systeem deze in de linksbovenhoek.
U kunt inhoud onder het besturingselementgebied voor bijschriften tekenen, zoals de achtergrond van uw app, maar u mag geen gebruikersinterface plaatsen waarmee u verwacht dat de gebruiker kan communiceren. Er wordt geen invoer ontvangen omdat invoer voor de besturingselementen voor bijschriften wordt verwerkt door het systeem.
In deze regels uit het vorige voorbeeld ziet u de opvullingskolommen in de XAML die de titelbalk definieert. Als u opvullingskolommen gebruikt in plaats van marges, zorgt u ervoor dat de achtergrond het gebied onder de ondertitelingsknoppen (voor transparante knoppen) schildert. Als u zowel rechter- als linkerpaddingkolommen gebruikt, zorgt u ervoor dat de titelbalk correct werkt in zowel rechts-naar-links- als links-naar-rechts-layouts.
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
De afmetingen en positie van het bijschriftcontrolegebied worden doorgegeven door de AppWindowTitleBar klasse, zodat u hiermee rekening kunt houden in de indeling van de gebruikersinterface van de titelbalk. De breedte van de gereserveerde regio aan elke zijde wordt gegeven door de eigenschappen LeftInset of RightInset en de hoogte ervan wordt gegeven door de eigenschap Height.
Hier ziet u hoe de breedte van de opvullingskolommen wordt opgegeven wanneer de sleepregio's worden berekend en ingesteld.
RightPaddingColumn.Width =
new GridLength(m_AppWindow.TitleBar.RightInset / scaleAdjustment);
LeftPaddingColumn.Width =
new GridLength(m_AppWindow.TitleBar.LeftInset / scaleAdjustment);
Belangrijk
Zie belangrijke informatie in de sectie Interactieve inhoud over hoe het schalen van weergaven van invloed is op deze waarden.
Ondersteuning voor hoge titelbalken voor aangepaste titelbalken
Wanneer u interactieve inhoud zoals een zoekvak of persoonsafbeelding toevoegt in de titelbalk, wordt u aangeraden de hoogte van de titelbalk te verhogen om meer ruimte te bieden voor deze elementen. Een hogere titelbalk maakt aanraakmanipulatie ook eenvoudiger. De eigenschap AppWindowTitleBar.PreferredHeightOption biedt u de mogelijkheid om de hoogte van de titelbalk te verhogen van de standaardhoogte, wat de standaardwaarde is, naar een hogere hoogte. Wanneer u de Tall
titelbalkmodus selecteert, worden de captionknoppen, die het systeem als een overlay in het clientgebied tekent, groter gemaakt met hun min/max/sluit-glyphs in het midden. Als u geen sleepregio hebt opgegeven, zal het systeem er een tekenen die zich uitstrekt over de breedte van uw venster en waarvan de hoogte wordt bepaald door de waarde PreferredHeightOption
die u hebt ingesteld.
In dit voorbeeld ziet u hoe u de eigenschap PreferredHeightOption
kunt instellen.
// A taller title bar is only supported when drawing a fully custom title bar.
if (ExtendsContentIntoTitleBar == true)
{
m_AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall;
}
Voorzichtigheid
De eigenschap AppWindowTitleBar.ExtendsContentIntoTitleBar moet true
zijn voordat u de eigenschap PreferredHeightOption
instelt. Als u PreferredHeightOption
probeert in te stellen terwijl ExtendsContentIntoTitleBar
is false
, wordt er een uitzondering gegenereerd.
Kleur en transparantie in bijschriftknoppen
Wanneer u uw app-inhoud uitbreidt naar het titelbalkgebied, kunt u de achtergrond van de bijschriftknoppen doorzichtig maken om uw app-achtergrond te laten zien. Doorgaans stelt u de achtergrond in op Colors.Transparent voor volledige transparantie. Voor gedeeltelijke doorzichtigheid stelt u het alfakanaal in voor de Color waarop u de eigenschap hebt ingesteld.
Deze eigenschappen van de titelbalk kunnen transparant zijn:
- KnopAchtergrondkleur
- ButtonHoverBackgroundColor
- AchtergrondkleurKnopIngedrukt
- ButtonInactiveBackgroundColor
Alle andere kleureigenschappen blijven het alfakanaal negeren. Als ExtendsContentIntoTitleBar
is ingesteld op false
, wordt het alfakanaal altijd genegeerd voor alle AppWindowTitleBar
kleureigenschappen.
De achtergrondkleur van de knop wordt niet toegepast op de Sluiten-knop in de hover-toestand () en ingedrukte toestand (). De knop Sluiten gebruikt altijd de door het systeem gedefinieerde kleur voor deze statussen.
Aanbeveling
Mica is een heerlijk materiaal dat helpt om het venster dat in focus is te onderscheiden. We raden het aan als achtergrond voor langlevende vensters in Windows 11. Als u Mica hebt toegepast in het clientgebied van uw venster, kunt u het uitbreiden naar het titelbalkgebied en uw vensterknoppen transparant maken zodat Mica zichtbaar wordt. Zie micamateriaal voor meer informatie.
De titelbalk dimen wanneer het venster inactief is
U moet het duidelijk maken wanneer uw venster actief of inactief is. U moet minimaal de kleur van de tekst, pictogrammen en knoppen in de titelbalk wijzigen.
Voor XAML-apps verwerkt u de gebeurtenis Window.Activated om de activeringsstatus van het venster te bepalen en werkt u de gebruikersinterface van de titelbalk indien nodig bij.
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"];
}
}
Voor andere UI-frameworks moet u een gebeurtenis afhandelen om de activeringsstatus van het venster te bepalen en de gebruikersinterface van de titelbalk indien nodig bij te werken. Hoe u de status van het venster bepaalt, is afhankelijk van het UI-framework dat u voor uw app gebruikt.
- Win32-: Luister en reageer op het WM_ACTIVATE bericht.
- WPF-: Window.Activated, Window.Deactivated.
- WinForms: Afhandelen Form.Activated, Form.Deactivate.
De titelbalk opnieuw instellen
Als u de systeemtitelbalk opnieuw wilt instellen of wilt overschakelen terwijl uw app wordt uitgevoerd, kunt u AppWindowTitleBar.ResetToDefaultaanroepen.
m_AppWindow.TitleBar.ResetToDefault();
Voor XAML-apps kunt u de titelbalk ook op de volgende manieren opnieuw instellen:
- Roep SetTitleBar aan om over te schakelen naar een nieuw titelbalkelement terwijl uw app wordt uitgevoerd.
- Roep
SetTitleBar
aan metnull
als parameter om de standaard slepen-regio's vanAppWindowTitleBar
opnieuw in te stellen. - Roep
SetTitleBar
aan metnull
als parameter en stel ExtendsContentIntoTitleBar in opfalse
om terug te keren naar de standaardbalk met systeemtitels.
De titelbalk weergeven en verbergen
Als u ondersteuning toevoegt voor volledig scherm of compacte overlay- modi aan uw app toevoegt, moet u mogelijk wijzigingen aanbrengen in de titelbalk wanneer uw app schakelt tussen deze modi. Het XAML-venster biedt geen API's ter ondersteuning van de modus Volledig scherm; hiervoor kunt u AppWindow-API's gebruiken.
Wanneer uw app wordt uitgevoerd in volledig scherm modus, verbergt het systeem de titelbalk- en bijschriftknoppen. U kunt de AppWindow.Changed-gebeurtenis afhandelen en de eventargs -eigenschap DidPresenterChange controleren om te bepalen of u de titelbalk moet weergeven, verbergen of wijzigen als reactie op een nieuwe weergave van het venster.
In dit voorbeeld ziet u hoe u de Changed
gebeurtenis kunt afhandelen om het AppTitleBar
element uit eerdere voorbeelden weer te geven en te verbergen. Als het venster in compacte overlay wordt geplaatst modus, wordt de titelbalk opnieuw ingesteld op de standaardbalk met systeemtitels (of u kunt een aangepaste titelbalk opgeven die is geoptimaliseerd voor compacte overlay).
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;
}
}
}
Notitie
Volledigscherm- en compacteoverlay- modi kunnen alleen worden ingevoerd als ze door uw app worden ondersteund. Zie App-vensters beheren, FullScreenPresenteren CompactOverlayPresenter- voor meer informatie.
Wat wel en niet te doen
- Maak het duidelijk wanneer uw venster actief of inactief is. Wijzig ten minste de kleur van de tekst, pictogrammen en knoppen in de titelbalk.
- Definieer een sleepgebied langs de bovenrand van het app-canvas. Door de plaatsing van systeemtitelbalken te vergelijken, is het gemakkelijker voor gebruikers om ze te vinden.
- Definieer een sleepregio die overeenkomt met de visuele titelbalk (indien aanwezig) op het canvas van de app.
Voorbeeld van volledige aanpassing
In deze voorbeelden ziet u alle code die wordt beschreven in de sectie Volledige aanpassing.
<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);
}
}
}
}
Verwante artikelen
Windows developer