Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Windows fournit une barre de titre par défaut pour chaque fenêtre et vous permet de la personnaliser afin qu’elle s’adapte à la personnalité de votre application. La barre de titre par défaut est fournie avec certains composants standard et des fonctionnalités de base telles que le déplacement et le redimensionnement de la fenêtre.
Consultez l’article de conception de barre de titre pour obtenir des conseils sur la personnalisation de la barre de titre de votre application, du contenu acceptable de la zone de barre de titre et des modèles d’interface utilisateur recommandés.
Important
Cet article explique comment personnaliser la barre de titre pour les applications qui utilisent le kit SDK d’application Windows, avec ou sans WinUI 3. Pour les applications qui utilisent UWP et WinUI 2, consultez Personnalisation de la barre de titre pour UWP.
Important
Un nouveau contrôle de barre de titre a été ajouté dans le Kit de développement logiciel (SDK) d’application Windows 1.7. Il simplifie le processus de personnalisation de la barre de titre.
- S’applique à : Kit de développement logiciel (SDK) d’application Windows, applications de bureau WinUI 3
- API importantes : propriété AppWindow.TitleBar, classe AppWindowTitleBar, classe AppWindow, classe Microsoft.UI.Xaml.Window, propriété Window.ExtendsContentIntoTitleBar, méthode Window.SetTitleBar
Composants de la barre de titre
Cette liste décrit les composants de la barre de titre standard.
- Rectangle de la barre de titre
- Texte du titre
- Icône système
- Menu système : accessible en cliquant sur l’icône d’application ou en cliquant avec le bouton droit de la souris sur la barre de titre
- Contrôles de légende
- Bouton Réduire
- Bouton Agrandir/Restaurer
- Bouton Fermer
Windowing
La fonctionnalité de fenêtrage dans le SDK d’application Windows s’opère via la classe Microsoft.UI.Windowing.AppWindow, qui repose sur le modèle Win32 HWND. Il existe un mappage individuel entre une AppWindow et une HWND de niveau supérieur dans votre application. AppWindow et ses classes associées fournissent des API qui vous permettent de gérer de nombreux aspects des fenêtres de niveau supérieur de votre application, y compris la personnalisation de la barre de titre. Vous pouvez modifier la barre de titre par défaut fournie par Windows afin qu’elle s’intègre au reste de votre interface utilisateur, ou étendre le canevas de votre application dans la zone de la barre de titre et fournir votre propre contenu de barre de titre.
La fonctionnalité de fenêtrage dans WinUI 3 est via la classe Microsoft.UI.Xaml.Window , qui est également basée sur le modèle HWND Win32. Pour les applications XAML qui utilisent WinUI 3, les API XAML Window offrent un moyen plus simple de personnaliser la barre de titre, tout en vous permettant d’accéder aux API AppWindow si nécessaire.
Fonctionnement d’AppWindow
Vous pouvez utiliser les API AppWindow avec n’importe quelle infrastructure d’interface utilisateur prise en charge par le SDK d’application Windows (Win32, WPF, WinForms ou WinUI 3), et vous pouvez les adopter de manière incrémentielle, en n’utilisant que les API dont vous avez besoin.
Si vous utilisez le code XAML WinUI 3 comme framework d’interface utilisateur de votre application, la fenêtre et les API AppWindow sont disponibles pour vous. À compter du Kit de développement logiciel (SDK) d’application Windows 1.4, la fenêtre XAML et AppWindow utilisent le même objet AppWindowTitleBar pour la personnalisation de la barre de titre. Utilisez la propriété Window.AppWindow pour obtenir un objet AppWindow à partir d’une fenêtre XAML existante. Avec cet objet AppWindow, vous avez accès aux API de personnalisation de la barre de titre.
Pour accéder aux fonctionnalités supplémentaires de la barre de titre, vous pouvez utiliser les API AppWindow à partir de la classe XAML Window comme suit : AppWindow.TitleBar.ForegroundColor = Colors.White;.
Si vous n’avez pas WinUI 3 1.3 ou version ultérieure, utilisez des API d’interopérabilité pour obtenir AppWindow et utilisez les API AppWindow pour personnaliser la barre de titre. Pour plus d’informations sur les API d’interopérabilité, consultez Gérer les fenêtres d’application – Infrastructure d’interface utilisateur et interopérabilité HWND et l’exemple de galerie de fenêtrage.
Étendue de la personnalisation de la barre de titre
Vous pouvez appliquer deux niveaux de personnalisation à la barre de titre : intégrer des modifications mineures à la barre de titre par défaut, ou étendre le canevas de votre application dans la zone de la barre de titre et fournir du contenu entièrement personnalisé.
Simple
Pour une personnalisation simple, telle que la modification de la couleur de la barre de titre, vous pouvez définir des propriétés sur l’objet AppWindowTitleBar afin de spécifier les couleurs que vous souhaitez utiliser pour les éléments de la barre de titre. Dans ce cas, le système reste en charge de tous les autres aspects de la barre de titre, tels que le dessin du titre de l’application et la définition des zones de glissement.
Full
L’autre option consiste à masquer la barre de titre système par défaut et à la remplacer par votre propre contenu personnalisé. Par exemple, vous pouvez placer du texte, une zone de recherche ou des menus personnalisés dans la zone de la barre de titre. Vous devrez également utiliser cette option pour étendre un arrière-plan matériel , comme Mica, dans la zone de barre de titre.
Lorsque vous optez pour une personnalisation complète, vous êtes responsable de la mise en place du contenu dans la zone de barre de titre, et vous pouvez définir vos propres zones de glissement. Les contrôles de légende (boutons système Fermer, Réduire et Agrandir) sont toujours disponibles et gérés par le système, mais les éléments tels que le titre de l’application ne le sont pas. Vous devrez créer ces éléments vous-même en fonction des besoins de votre application.
Personnalisation simple
Si vous souhaitez personnaliser uniquement le titre, les couleurs ou l’icône de la barre de titre, vous pouvez définir des propriétés sur l’objet de barre de titre de la fenêtre de votre application.
Title
Par défaut, la barre de titre affiche le type d’application comme titre de la fenêtre (par exemple, « WinUI Desktop »). Vous devez mettre à jour le titre de la fenêtre de façon à afficher un nom explicite pour votre application.
Une application XAML a un nom d’affichage défini dans le fichier Package.appxmanifest. Vous pouvez obtenir cette valeur et l’utiliser pour définir la propriété Title comme ceci.
Title = AppInfo.Current.DisplayInfo.DisplayName;
Pour modifier le titre de la fenêtre, définissez la propriété Window.Title sur une valeur de texte à une seule ligne, comme indiqué ici.
<Window
...
Title="App title">
...
</Window>
public MainWindow()
{
InitializeComponent();
Title = "App title";
}
Pour modifier le titre de la fenêtre à l’aide des API AppWindow, définissez la propriété AppWindow.Title sur une valeur de texte à une seule ligne, comme illustré ici. Cet exemple montre comment utiliser des API d’interopérabilité pour obtenir AppWindow, qui est nécessaire si votre application n’utilise pas WinUI 3 1.3 ou version ultérieure.
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
Pour personnaliser les couleurs de la barre de titre par défaut ou pour modifier l’icône de fenêtre par défaut, vous devez utiliser les API AppWindow ou choisir de personnaliser entièrement votre barre de titre.
Cet exemple montre comment obtenir une instance d’AppWindowTitleBar et définir ses propriétés de couleur.
Important
La personnalisation des couleurs est ignorée lorsque l’application s’exécute sur 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;
}
Voici quelques points à prendre en compte lors de la définition des couleurs de la barre de titre :
- La couleur d’arrière-plan du bouton n’est pas appliquée au pointage du bouton fermer et les états appuyés . Le bouton Fermer utilise toujours la couleur définie par le système pour ces états.
- L’affectation de la valeur
nullà une propriété de couleur entraîne le rétablissement de la couleur système par défaut. - Vous ne pouvez pas définir de couleurs transparentes. Le canal alpha de la couleur est ignoré.
Windows permet à l’utilisateur d’appliquer sa couleur d’accentuation sélectionnée à la barre de titre. Si vous définissez une couleur de barre de titre, nous vous recommandons de définir explicitement toutes les couleurs. Vous éviterez ainsi les combinaisons de couleurs involontaires qui se produisent en raison des paramètres de couleur définis par l’utilisateur.
Icône et menu système
Vous pouvez masquer l’icône système ou la remplacer par une icône personnalisée. L’icône système affiche le menu système lorsqu’un utilisateur y effectue un clic droit ou appuie dessus. Elle ferme la fenêtre lorsque l’utilisateur y effectue un clic droit ou appuie dessus.
Pour afficher ou masquer l’icône système et les comportements associés, définissez la propriété IconShowOptions de la barre de titre.
m_TitleBar.IconShowOptions = IconShowOptions.HideIconAndSystemMenu;
Pour utiliser une icône de fenêtre personnalisée, appelez l’une des méthodes AppWindow.SetIcon pour définir la nouvelle icône.
SetIcon(String)La méthode SetIcon(String) fonctionne actuellement uniquement avec les fichiers .ico. La chaîne que vous transmettez à cette méthode est le chemin complet du fichier .ico.
m_AppWindow.SetIcon("iconPath/iconName.ico");SetIcon(IconId)Si vous disposez déjà d’un handle vers une icône (
HICON) à partir de l’une des fonctions Icon comme CreateIcon, vous pouvez utiliser l’API d’interopérabilité GetIconIdFromIcon pour obtenir un IconId. Vous pouvez ensuite passer laIconIdméthode SetIcon(IconId) pour définir votre icône de fenêtre.m_AppWindow.SetIcon(iconId));
Personnalisation complète
Lorsque vous optez pour la personnalisation complète de la barre de titre, la zone cliente de votre application est étendue de façon à couvrir toute la fenêtre, y compris la zone de barre de titre. Vous êtes responsable du dessin et de la gestion des entrées pour l’ensemble de la fenêtre, à l’exception des boutons de légende, qui sont toujours fournis par la fenêtre.
Pour masquer la barre de titre système et étendre votre contenu dans la zone de barre de titre, affectez la valeur true à la propriété qui étend le contenu de l’application dans la zone de barre de titre. Dans une application XAML, cette propriété peut être définie dans la méthode de votre application OnLaunched (App.xaml.cs) ou dans la première page de votre application.
Tip
Consultez la section Exemple de personnalisation complète pour voir tout le code en même temps.
Cet exemple montre comment définir la propriété trueWindow.ExtendsContentIntoTitleBar sur .
public MainWindow()
{
this.InitializeComponent();
// Hide system title bar.
ExtendsContentIntoTitleBar = true;
}
Caution
ExtendsContentIntoTitleBar s’affiche dans XAML IntelliSense pour Window, mais sa définition en XAML provoque une erreur. Définissez plutôt cette propriété dans le code.
Cet exemple montre comment obtenir AppWindowTitleBar et définir la propriété trueAppWindowTitleBar.ExtendsContentIntoTitleBar sur . Cet exemple montre comment utiliser des API d’interopérabilité pour obtenir AppWindow, qui est nécessaire si votre application n’utilise pas WinUI 3 1.3 ou version ultérieure.
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);
}
Contenu de la barre de titre et zone de glissement par défaut
Lorsque votre application est étendue à la zone de barre de titre, vous êtes responsable de la définition et de la gestion de l’interface utilisateur pour la barre de titre. Cela inclut généralement, au minimum, la spécification du texte de titre et de la zone de glissement. La zone de glissement de la barre de titre définit l’emplacement où l’utilisateur peut cliquer et faire glisser pour déplacer la fenêtre à un autre endroit. C’est également là que l’utilisateur peut cliquer avec le bouton droit de la souris pour afficher le menu système.
Pour en savoir plus sur le contenu acceptable de la barre de titre et les modèles d’interface utilisateur recommandés, consultez Conception de la barre de titre.
Cet exemple montre le XAML pour une interface utilisateur de barre de titre personnalisée sans contenu interactif.
<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
LeftPaddingColumn et RightPaddingColumn sont utilisés afin de réserver de l’espace pour les boutons de légende. Les valeurs Width pour ces colonnes sont définies dans le code, qui est affiché plus loin. Pour obtenir le code et l’explication, consultez la section Boutons de légende système.
Une application XAML a un nom d’affichage défini dans le fichier Package.appxmanifest. Vous pouvez obtenir cette valeur et l’utiliser dans votre barre de titre personnalisée comme suit.
TitleBarTextBlock.Text = AppInfo.Current.DisplayInfo.DisplayName;
Lorsque vous étendez votre contenu dans la zone de barre de titre, la barre de titre système est masquée et une barre de titre AppWindowTitleBar par défaut est créée qui fournit des boutons de légende et une zone de glissement sur la largeur de l’écran, identique à la barre de titre système. Si vous ne placez pas de contenu interactif dans la barre de titre, vous pouvez laisser cette zone de glissement par défaut en l’état. Si vous placez du contenu interactif dans la barre de titre, vous devez spécifier les zones interactives, procédure que nous abordons dans la section suivante.
Caution
Lorsque vous définissez des zones de glissement personnalisées, elles n’ont pas besoin d’être en haut de la fenêtre dans la zone de barre de titre par défaut. Vous pouvez définir n’importe quelle partie de votre interface utilisateur en tant que zone de glissement. Toutefois, si vous placez des zones de glissement à différents endroits, il sera peut-être compliqué pour vos utilisateurs de les découvrir.
Contenu interactif
Vous pouvez placer des contrôles interactifs, tels que des boutons, des menus ou une zone de recherche, dans la partie supérieure de l’application afin qu’ils apparaissent dans la barre de titre. Toutefois, vous devez spécifier les zones qui sont interactives, afin de vous assurer que les éléments interactifs recevront une entrée utilisateur tout en permettant aux utilisateurs de déplacer votre fenêtre.
Lorsque vous ajoutez du contenu interactif dans la zone de barre de titre, vous devez utiliser la classe InputNonClientPointerSource pour spécifier les zones dans lesquelles l’entrée est transmise au contrôle interactif, plutôt que gérée par la barre de titre. Pour définir les régions interactives, appelez la méthode InputNonClientPointerSource.SetRegionRects . Cette méthode utilise une valeur qui spécifie le type de zone définie (en l’occurrence Passthrough) et un tableau de rectangles, chacun définissant une zone Passthrough. Lorsque la taille de la barre de titre change, vous devez recalculer les zones interactives afin qu’elles correspondent à la nouvelle taille, et appeler SetRegionRects avec les nouvelles valeurs.
Cet exemple montre une interface utilisateur de barre de titre personnalisée avec une zone de recherche et un contrôle de compte PersonPicture. Il montre comment calculer et définir les rectangles interactifs pour ces contrôles afin que l’entrée leur soit transmise.
Voici quelques points importants à noter concernant ce code :
- Définissez la
AppTitleBarhauteur de la grille sur 48 pour suivre les instructions de conception de la barre de titre pour le contenu interactif. - Définissez PreferredHeightOption
Tallpour que les boutons de légende soient de la même hauteur que la barre de titre. - Pour faciliter le redimensionnement des contrôles et le calcul des zones, utilisez un objet
Gridavec plusieurs colonnes nommées pour la mise en page. - Utilisez le dimensionnement en étoile (*) avec
MinWidthpour la colonne qui contient laAutoSuggestBoxvaleur afin qu’elle soit automatiquement redimensionnée avec la fenêtre. - Définissez
MinWidthsur l’objetRightDragColumnafin de réserver une petite zone toujours déplaçable, même lorsque la fenêtre est redimensionnée. - Affectez la valeur
ExtendsContentIntoTitleBaràtruedans le constructeur MainWindow. Si vous définissez cette propriété dans du code qui sera appelé ultérieurement, la barre de titre système par défaut peut être affichée en premier, puis masquée. - Effectuez l’appel initial pour calculer les zones interactives une fois l’élément
AppTitleBarchargé. Dans le cas contraire, il n’y a aucune garantie que les éléments utilisés pour le calcul auront leurs valeurs correctes. - Ne mettez à jour les calculs du rectangle interactif uniquement qu’une fois que l’élément
AppTitleBara changé de taille (AppTitleBar_SizeChanged). Si vous dépendez de l’événement de fenêtreChanged, il existe des situations (par exemple, agrandissement/réduction de la fenêtre) où l’événement se produit avant queAppTitleBarsoit redimensionné et où les calculs utilisent des valeurs incorrectes. - Ne définissez vos zones interactives/de glissement personnalisées qu’après avoir vérifié
ExtendsContentIntoTitleBarafin de confirmer qu’une barre de titre personnalisée est utilisée.
<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>
Ce code montre comment calculer et définir les régions interactives qui correspondent aux contrôles AutoSuggestBox et 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 utilise des pixels physiques pour la compatibilité avec les infrastructures d’interface utilisateur non basées sur des coordonnées logiques. Si vous utilisez WPF ou WinUI 3, RightInset, LeftInset et les valeurs utilisées pour calculer les zones doivent être ajustées si l’échelle d’affichage n’est pas 100 %. Dans cet exemple, nous obtenons une valeur scaleAdjustment pour représenter le paramètre d’échelle d’affichage.
- Pour WinUI 3, utilisez la propriété XamlRoot.RasterizationScale pour obtenir l’ajustement de l’échelle.
- Pour WPF, vous pouvez gérer l’événement Window.DpiChanged pour obtenir la valeur NewDpi et calculer l’ajustement de l’échelle.
Boutons de légende système
Le système réserve le coin supérieur gauche ou supérieur droit de la fenêtre d’application pour les boutons de légende système (réduire, agrandir/restaurer, fermer). Le système conserve le contrôle de la zone de boutons de légende afin de garantir qu’un minimum de fonctionnalités sont fournies pour le déplacement, la réduction, l’agrandissement et la fermeture de la fenêtre. Le système dessine le bouton Fermer en haut à droite pour les langues qui se lisent de gauche à droite, et en haut à gauche pour les langues qui se lisent de droite à gauche.
Vous pouvez dessiner du contenu sous la zone du contrôle de légende, comme l’arrière-plan de votre application, mais vous ne devez pas y placer d’interface utilisateur avec laquelle vous prévoyez que l’utilisateur interagisse. Cette zone ne reçoit aucune entrée, car l’entrée pour les contrôles de légende est gérée par le système.
Ces lignes issues de l’exemple précédent montrent les colonnes de remplissage dans le code XAML qui définit la barre de titre. L’utilisation de colonnes de remplissage au lieu de marges garantit que l’arrière-plan peint la zone sous les boutons de contrôle de légende (pour les boutons transparents). L’utilisation de colonnes de remplissage à droite et à gauche garantit que la barre de titre se comporte correctement à la fois dans les mises en page lues de droite à gauche et celles qui sont lues de gauche à droite.
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>
<ColumnDefinition/>
<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>
</Grid.ColumnDefinitions>
Les dimensions et la position de la zone de contrôle de légende sont communiquées par la classe AppWindowTitleBar afin que vous puissiez le prendre en compte dans la disposition de l’interface utilisateur de la barre de titre. La largeur de la région réservée de chaque côté est donnée par les propriétés LeftInset ou RightInset , et sa hauteur est donnée par la propriété Height .
Voici comment la largeur des colonnes de remplissage est spécifiée lorsque les zones de glissement sont calculées et définies.
RightPaddingColumn.Width =
new GridLength(m_AppWindow.TitleBar.RightInset / scaleAdjustment);
LeftPaddingColumn.Width =
new GridLength(m_AppWindow.TitleBar.LeftInset / scaleAdjustment);
Important
Consultez les informations importantes de la section contenu interactif sur la façon dont la mise à l’échelle de l’affichage affecte ces valeurs.
Prise en charge des barres de titre hautes pour les barres de titre personnalisées
Lorsque vous ajoutez du contenu interactif comme une zone de recherche ou la photo d’une personne dans la barre de titre, nous vous recommandons d’augmenter la hauteur de la barre de titre afin de laisser davantage d’espace à ces éléments. Une barre de titre plus haute facilite également la manipulation tactile. La propriété AppWindowTitleBar.PreferredHeightOption vous donne la possibilité d’augmenter la hauteur de la barre de titre de la hauteur standard, qui est la hauteur par défaut, à une hauteur plus élevée. Lorsque vous sélectionnez le mode barre de titre Tall, les boutons de légende dessinés par le système en tant que superposition dans la zone cliente sont affichés plus hauts avec leurs glyphes min/max/fermé centrés. Si vous n’avez pas spécifié de zone de glissement, le système en dessine une qui étend la largeur de la fenêtre et la hauteur déterminée par la valeur PreferredHeightOption que vous avez définie.
Cet exemple montre comment définir la propriété 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
La propriété AppWindowTitleBar.ExtendsContentIntoTitleBar doit être true avant de définir la PreferredHeightOption propriété. Si vous tentez de définir PreferredHeightOption pendant que ExtendsContentIntoTitleBar est false, une exception est générée.
Couleur et transparence des boutons de légende
Lorsque vous étendez le contenu de votre application dans la zone de barre de titre, vous pouvez rendre l’arrière-plan des boutons de légende transparents afin que l’arrière-plan de votre application soit visible. Vous définissez généralement l’arrière-plan sur Colors.Transparent pour une transparence totale. Pour une transparence partielle, définissez le canal alpha de la couleur sur laquelle vous définissez la propriété.
Ces propriétés de barre de titre peuvent être transparentes :
- ButtonBackgroundColor
- ButtonHoverBackgroundColor
- ButtonPressedBackgroundColor
- ButtonInactiveBackgroundColor
Toutes les autres propriétés de couleur continueront à ignorer le canal alpha. Si ExtendsContentIntoTitleBar a la valeur false, le canal alpha reste ignoré pour toutes les propriétés de couleur AppWindowTitleBar.
La couleur d’arrière-plan du bouton n’est pas appliquée au pointage du bouton Fermer et les états appuyés . Le bouton Fermer utilise toujours la couleur définie par le système pour ces états.
Tip
Mica est un matériau agréable qui permet de distinguer la fenêtre qui est en focus. Nous le recommandons comme arrière-plan pour les fenêtres durables dans Windows 11. Si vous avez appliqué Mica dans la zone cliente de la fenêtre, vous pouvez l’étendre dans la zone de barre de titre et rendre les boutons de légende transparents afin que Mica soit visible. Pour plus d’informations, consultez le matériel Mica .
Estomper la barre de titre lorsque la fenêtre est inactive
Le caractère actif ou inactif de la fenêtre doit être une évidence. Au minimum, vous devez modifier la couleur du texte, des icônes et des boutons dans la barre de titre.
Pour les applications XAML, gérez l’événement Window.Activated pour déterminer l’état d’activation de la fenêtre et mettez à jour l’interface utilisateur de la barre de titre en fonction des besoins.
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"];
}
}
Pour d’autres infrastructures d’interface utilisateur, gérez un événement afin de déterminer l’état d’activation de la fenêtre et mettez à jour l’interface utilisateur de la barre de titre en fonction des besoins. La façon dont vous déterminez l’état de la fenêtre dépend de l’infrastructure d’interface utilisateur que vous utilisez pour votre application.
- Win32 : écoutez et répondez au message WM_ACTIVATE .
- WPF : Handle Window.Activated, Window.Deactivated.
- WinForms : Handle Form.Activated, Form.Deactivate.
Réinitialiser la barre de titre
Pour réinitialiser ou basculer vers la barre de titre système pendant l’exécution de votre application, vous pouvez appeler AppWindowTitleBar.ResetToDefault.
m_AppWindow.TitleBar.ResetToDefault();
Pour les applications XAML, vous pouvez également réinitialiser la barre de titre des manières suivantes :
- Appelez SetTitleBar pour basculer vers un nouvel élément de barre de titre pendant l’exécution de votre application.
- Appelez
SetTitleBaravecnullcomme paramètre pour rétablir les zones de glissementAppWindowTitleBarpar défaut. - Appelez
SetTitleBaravecnullle paramètre et définissez ExtendsContentIntoTitleBar pourfalserevenir à la barre de titre système par défaut.
Afficher et masquer la barre de titre
Si vous ajoutez la prise en charge des modes de superposition plein écran ou compact à votre application, vous devrez peut-être apporter des modifications à votre barre de titre lorsque votre application passe d’un mode à l’autre. La fenêtre XAML ne fournit aucune API pour prendre en charge le mode plein écran. Vous pouvez utiliser les API AppWindow pour cela.
Lorsque votre application s’exécute en mode plein écran , le système masque les boutons de contrôle de barre de titre et de légende. Vous pouvez gérer l’événement AppWindow.Changed et vérifier la propriété DidPresenterChange d’événement pour déterminer si vous devez afficher, masquer ou modifier la barre de titre en réponse à une nouvelle présentation de fenêtre.
Cet exemple montre comment gérer l’événement Changed pour afficher et masquer l’élément AppTitleBar des exemples précédents. Si la fenêtre est placée en mode superposition compacte , la barre de titre est réinitialisée à la barre de titre système par défaut (ou vous pouvez fournir une barre de titre personnalisée optimisée pour la superposition compacte).
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
Les modes de superposition plein écran et compact peuvent être entrés uniquement si votre application est prise en charge. Pour plus d’informations, consultez Gérer les fenêtres d’application, FullScreenPresenter et CompactOverlayPresenter.
Pratiques conseillées et déconseillées
- Le caractère actif ou inactif de la fenêtre doit être une évidence. Au minimum, modifiez la couleur du texte, des icônes et des boutons dans la barre de titre.
- Définissez une zone de glissement le long du bord supérieur du canevas de l’application. La mise en correspondance de l’emplacement des barres de titre système permet aux utilisateurs de les trouver plus facilement.
- Définissez une zone de glissement qui correspond à la barre de titre visuelle (le cas échéant) sur le canevas de l’application.
Exemple de personnalisation complète
Cet exemple montre tout le code décrit dans la section Personnalisation complète.
<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);
}
}
}
}
Articles connexes
Windows developer