Vue d’ensemble des fenêtres WPF (WPF .NET)

Les utilisateurs interagissent avec des applications Windows Presentation Foundation (WPF) via Windows. L’objectif principal d’une fenêtre est d’héberger du contenu qui permet aux utilisateurs de visualiser les données et d’interagir avec celles-ci. Les applications WPF fournissent leurs propres fenêtres à l’aide de la classe Window. Cet article présente Window avant de couvrir les principes fondamentaux de la création et de la gestion de fenêtres dans les applications.

Important

Cet article utilise le code XAML généré à partir d’un projet C#. Si vous utilisez Visual Basic, le code XAML peut sembler légèrement différent. Ces différences sont généralement présentes sur les valeurs d’attribut x:Class. C# inclut l’espace de noms racine du projet alors que Visual Basic ne le fait pas.

Les modèles de projet pour C# créent un type App contenu dans le fichier app.xaml. En Visual Basic, le type est nommé Application et le fichier est nommé Application.xaml.

Classe Window

Dans WPF, une fenêtre est encapsulée par la classe Window que vous utilisez pour effectuer les opérations suivantes :

  • afficher une fenêtre ;
  • configurer la taille, la position et l’apparence d’une fenêtre ;
  • héberger un contenu spécifique à l’application ;
  • gérer la durée de vie d’une fenêtre.

La figure suivante illustre les éléments constitutifs d’une fenêtre :

Capture d’écran montrant des parties d’une fenêtre WPF.

Une fenêtre est divisée en deux zones : la zone non cliente et la zone cliente.

La zone non cliente d’une fenêtre est implémentée par WPF et inclut les parties d’une fenêtre qui sont communes à la plupart des fenêtres, notamment les éléments suivants :

  • Une barre de titre (1-5).
  • Une icône (1).
  • Titre (2).
  • Boutons Réduire (3), Agrandir (4) et Fermer (5).
  • Menu système (6) avec des éléments de menu. Apparaît lorsque vous cliquez sur l’icône (1).
  • Bordure (7).

La zone cliente d’une fenêtre est la zone située dans la zone non cliente d’une fenêtre, qui permet aux développeurs d’ajouter du contenu spécifique à une application, par exemple des barres de menus, des barres d’outils et des contrôles.

  • Zone Cliente (8).
  • Redimensionner la poignée (9). Il s’agit d’un contrôle ajouté à la zone cliente (8).

Implémentation d’une fenêtre

L’implémentation d’une fenêtre classique comprend à la fois son apparence et son comportement. L’apparence définit l’aspect d’une fenêtre pour les utilisateurs et le comportement définit le mode de fonctionnement d’une fenêtre quand les utilisateurs interagissent avec elle. Dans WPF, vous pouvez implémenter l’apparence et le comportement d’une fenêtre par du code ou du balisage XAML.

En général, toutefois, l’apparence d’une fenêtre est implémentée via du balisage XAML, et son comportement est implémenté via du code-behind, comme le montre l’exemple suivant.

<Window x:Class="WindowsOverview.Window1"
        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"
        xmlns:local="clr-namespace:WindowsOverview"
        >

    <!-- Client area containing the content of the window -->
    
</Window>

Le code suivant est le code-behind pour le code XAML.

using System.Windows;

namespace WindowsOverview
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}
Public Class Window1

End Class

Pour permettre à un fichier de balisage XAML et à un fichier code-behind de fonctionner ensemble, les éléments suivants sont nécessaires :

  • Dans le balisage, l’élément Window doit inclure l’attribut x:Class. Une fois l’application générée, l’existence de l’attribut x:Class pousse Microsoft Build Engine (MSBuild) à générer une classe partial qui dérive de Window et qui porte le nom spécifié par l’attribut x:Class. Cela nécessite l’ajout d’une déclaration d’espace de noms XML pour le schéma XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"). La classe partial générée implémente la méthode InitializeComponent, qui est appelé pour inscrire les événements et définir les propriétés implémentées dans le balisage.

  • Dans du code-behind, la classe doit être une classe partial portant le nom spécifié par l’attribut x:Class dans le balisage, et doit dériver de Window. Cela permet au fichier code-behind d’être associé à la classe partial générée pour le fichier de balisage quand l’application est générée, pour plus d’informations, consultez Compiler une application WPF.

  • Dans du code-behind, la classe Window doit implémenter un constructeur qui appelle la méthode InitializeComponent. InitializeComponent est implémenté par la classe générée partial du fichier de balisage pour inscrire les événements et définir les propriétés définies dans le balisage.

Remarque

Quand vous ajoutez un nouveau Window à votre projet en utilisant Visual Studio, Window est implémenté à l’aide du balisage et du code-behind, et inclut la configuration nécessaire pour créer l’association entre les fichiers de balisage et les fichiers code-behind, comme décrit ici.

Une fois cette configuration en place, vous pouvez vous concentrer sur la définition de l’apparence de la fenêtre dans le balisage XAML et sur l’implémentation de son comportement dans du code-behind. L’exemple suivant montre une fenêtre avec un bouton qui définit un gestionnaire d’événements pour l’événement Click. Cela est implémenté dans le code XAML et le gestionnaire est implémenté dans le code-behind.

<Window x:Class="WindowsOverview.Window1"
        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"
        xmlns:local="clr-namespace:WindowsOverview"
        >

    <!-- Client area containing the content of the window -->

    <Button Click="Button_Click">Click This Button</Button>
    
</Window>

Le code suivant est le code-behind pour le code XAML.

using System.Windows;

namespace WindowsOverview
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Button was clicked.");
        }
    }
}
Public Class Window1

    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        MessageBox.Show("Button was clicked.")
    End Sub

End Class

Configuration d’une fenêtre pour MSBuild

La façon dont vous implémentez votre fenêtre détermine la façon dont elle est configurée pour MSBuild. Pour une fenêtre définie à l’aide du balisage XAML et du code-behind :

  • Les fichiers de balisage XAML sont configurés en tant qu’éléments Page MSBuild.
  • Les fichiers code-behind sont configurés en tant qu’éléments Compile MSBuild.

Les projets du Kit de développement logiciel (SDK) .NET importent automatiquement les éléments appropriés Page et Compile vous n’avez pas besoin de les déclarer. Lorsque le projet est configuré pour WPF, les fichiers de balisage XAML sont automatiquement importés en tant qu’éléments Page, et le fichier code-behind correspondant est importé en tant que Compile.

Les projets MSBuild n’importent pas automatiquement les types et vous devez les déclarer vous-même :

<Project>
    ...
    <Page Include="MarkupAndCodeBehindWindow.xaml" />
    <Compile Include=" MarkupAndCodeBehindWindow.xaml.cs" />
    ...
</Project>

Pour plus d’informations sur la génération d’applications WPF, consultez Compilation d’une application WPF.

Durée de vie d'une fenêtre

Comme pour toute classe, une fenêtre a une durée de vie qui commence quand elle est instanciée pour la première fois. Elle est ensuite ouverte, activée/désactivée, et finalement fermée.

Ouverture d’une fenêtre

Pour ouvrir une fenêtre, commencez par créer une instance de celle-ci, comme le montre l’exemple suivant :

using System.Windows;

namespace WindowsOverview
{
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // Create the window
            Window1 window = new Window1();

            // Open the window
            window.Show();
        }
    }
}
Class Application

    Private Sub Application_Startup(sender As Object, e As StartupEventArgs)
        ' Create the window
        Dim window As New Window1

        ' Open the window
        window.Show()
    End Sub

End Class

Dans cet exemple, Window1 est instancié au démarrage de l’application, lequel a lieu quand l’événement Startup est déclenché. Pour plus d’informations sur la fenêtre de démarrage, consultez Comment obtenir ou définir la fenêtre principale de l’application.

Lorsqu’une fenêtre est instanciée, une référence à celle-ci est automatiquement ajoutée à une liste de fenêtres gérées par l’objet Application. La première fenêtre à instancier est automatiquement définie par Application comme la fenêtre principale de l’application.

La fenêtre est enfin ouverte en appelant la méthode Show , comme illustré dans l’image suivante :

Fenêtre WPF avec un bouton unique à l’intérieur avec le texte « Cliquez sur moi ».

Une fenêtre ouverte en appelant Show est une fenêtre sans mode et l’application n’empêche pas les utilisateurs d’interagir avec d’autres fenêtres de l’application. L’ouverture d’une fenêtre avec ShowDialog ouvre une fenêtre en tant que modale et limite l’interaction de l’utilisateur à la fenêtre spécifique. Pour plus d’informations, consultez Vue d’ensemble des boîtes de dialogue.

Quand Show est appelé, une fenêtre exécute un travail d’initialisation avant d’être affichée pour établir une infrastructure lui permettant de recevoir une entrée d’utilisateur. Lorsque la fenêtre est initialisée, l’événement SourceInitialized est déclenché et la fenêtre s’affiche.

Pour plus d’informations, voir Comment ouvrir une fenêtre ou une boîte de dialogue.

Fenêtre de démarrage

L’exemple précédent a utilisé l’événement Startup pour exécuter du code qui affichait la fenêtre d’application initiale. En guise de raccourci, utilisez StartupUri plutôt pour spécifier le chemin d’accès à un fichier XAML dans votre application. L’application crée et affiche automatiquement la fenêtre spécifiée par cette propriété.

<Application x:Class="WindowsOverview.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WindowsOverview"
             StartupUri="ClippedWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

Appartenance de la fenêtre

Une fenêtre ouverte à l’aide de la méthode Show n’a pas de relation implicite avec la fenêtre qui l’a créée. Les utilisateurs peuvent interagir avec l’une ou l’autre fenêtre indépendamment de l’autre, ce qui signifie que l’une ou l’autre des fenêtres peut effectuer les opérations suivantes :

  • Couvrir l’autre (sauf si l’une des fenêtres a sa propriété Topmost définie sur true).
  • être réduite, agrandie et restaurée sans affecter l’autre fenêtre.

Certaines fenêtres nécessitent une relation avec la fenêtre qui les ouvre. Par exemple, une application Environnement de développement intégré (IDE) peut ouvrir des fenêtres de propriétés et des fenêtres Outil dont le comportement classique est de couvrir la fenêtre qui les crée. De plus, ces fenêtres doivent toujours se fermer, se réduire, s’agrandir et se restaurer conjointement avec la fenêtre qui les a créées. Vous pouvez établir une telle relation en faisant en sorte qu’une fenêtre en possède une autre. Pour ce faire, affectez à la propriété Owner de la fenêtre possédée une référence à la fenêtre propriétaire. Cela est illustré par l'exemple suivant.

private void Button_Click(object sender, RoutedEventArgs e)
{
    // Create a window and make the current window its owner
    var ownedWindow = new ChildWindow1();
    ownedWindow.Owner = this;
    ownedWindow.Show();
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
    ' Create a window and make the current window its owner
    Dim ownedWindow As New ChildWindow1
    ownedWindow.Owner = Me
    ownedWindow.Show()
End Sub

Une fois la propriété établie :

  • La fenêtre possédée peut référencer sa fenêtre propriétaire en consultant la valeur de sa propriété Owner.
  • La fenêtre propriétaire peut découvrir toutes les fenêtres qu’elle possède en consultant la valeur de sa propriété OwnedWindows.

Activation de la fenêtre

Lorsqu’une fenêtre est ouverte pour la première fois, elle devient la fenêtre active. La fenêtre active est la fenêtre qui capture les entrées des utilisateurs, par exemple les séquences de touches et les clics de souris. Lorsqu’une fenêtre devient active, elle déclenche l’événement Activated.

Remarque

Lorsqu’une fenêtre est ouverte pour la première fois, les événements Loaded et ContentRendered sont déclenchés uniquement une fois l’événement Activated déclenché. Ainsi, une fenêtre peut effectivement être considérée comme ouverte quand ContentRendered est déclenché.

Une fois qu’une fenêtre est active, un utilisateur peut activer une autre fenêtre de la même application ou activer une autre application. Quand cela se produit, la fenêtre active est désactivée et déclenche l’événement Deactivated. De même, quand l’utilisateur sélectionne une fenêtre désactivée, celle-ci redevient active et Activated est déclenché.

Une des raisons courantes de gérer Activated et Deactivated consiste à activer et désactiver les fonctionnalités qui peuvent s’exécuter uniquement lorsqu’une fenêtre est active. Par exemple, certaines fenêtres affichent du contenu interactif qui nécessite en permanence l’attention de l’utilisateur ou une entrée de sa part, notamment les jeux et les lecteurs vidéo. L’exemple suivant est un lecteur vidéo simplifié qui montre comment gérer Activated et Deactivated pour implémenter ce comportement.

<Window x:Class="WindowsOverview.CustomMediaPlayerWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Activated="Window_Activated"
        Deactivated="Window_Deactivated"
        Title="CustomMediaPlayerWindow" Height="450" Width="800">
    <Grid>
        <MediaElement x:Name="mediaElement" Stretch="Fill"
                      LoadedBehavior="Manual" Source="numbers.mp4" />
    </Grid>
</Window>

Le code suivant est le code-behind pour le code XAML.

using System;
using System.Windows;

namespace WindowsOverview
{
    public partial class CustomMediaPlayerWindow : Window
    {
        public CustomMediaPlayerWindow() =>
            InitializeComponent();

        private void Window_Activated(object sender, EventArgs e)
        {
            // Continue playing media if window is activated
            mediaElement.Play();
        }

        private void Window_Deactivated(object sender, EventArgs e)
        {
            // Pause playing if media is being played and window is deactivated
            mediaElement.Pause();
        }
    }
}
Public Class CustomMediaPlayerWindow
    Private Sub Window_Activated(sender As Object, e As EventArgs)
        ' Continue playing media if window Is activated
        mediaElement.Play()
    End Sub

    Private Sub Window_Deactivated(sender As Object, e As EventArgs)
        ' Pause playing if media is being played and window is deactivated
        mediaElement.Pause()
    End Sub
End Class

D’autres types d’application peuvent toujours exécuter du code en arrière-plan quand une fenêtre est désactivée. Par exemple, un client d’e-mail peut continuer à interroger le serveur d’e-mail pendant que l’utilisateur utilise d’autres applications. Les applications de ce type ont souvent un comportement différent ou supplémentaire pendant que la fenêtre principale est désactivée. Pour un programme d’e-mail, cela peut signifier l’ajout du nouvel élément d’e-mail à la boîte de réception, ainsi que l’ajout d’une icône de notification à la zone de notification. Une icône de notification doit être affichée uniquement quand la fenêtre d’e-mail n’est pas active, ce qui est déterminé via l’examen de la propriété IsActive.

À la fin d’une tâche en arrière-plan, vous pouvez notifier plus rapidement l’utilisateur à l’aide d’une fenêtre en appelant la méthode Activate. Si l’utilisateur interagit avec une autre application activée quand Activate est appelé, le bouton de la barre des tâches de la fenêtre clignote. Cependant, si un utilisateur interagit avec l’application active, l’appel de Activate amène la fenêtre au premier plan.

Remarque

Vous pouvez gérer l’activation de l’étendue de l’application à l’aide des événements Application.Activated et Application.Deactivated .

Blocage de l’activation de la fenêtre

Dans certains scénarios, les fenêtres ne doivent pas être activées quand elles sont affichées (fenêtres de conversation d’une application de messagerie instantanée ou fenêtres de notification d’une application d’e-mail, par exemple).

Si votre application a une fenêtre qui ne doit pas être activée quand elle est affichée, vous pouvez affecter à sa propriété ShowActivated la valeur false avant d’appeler la méthode Show pour la première fois. En conséquence :

  • La fenêtre n’est pas activée.
  • L’événement Activated de la fenêtre n’est pas déclenché.
  • La fenêtre déjà activée reste activée.

Toutefois, la fenêtre est activée dès que l’utilisateur clique sur la zone cliente ou non cliente. Dans ce cas :

  • La fenêtre est activée.
  • L’événement Activated de la fenêtre est déclenché.
  • La fenêtre qui était activée est désactivée.
  • Les événements Deactivated et Activated de la fenêtre sont ensuite déclenchés comme prévu en réponse aux actions utilisateur.

Fermeture d’une fenêtre

Quand un utilisateur ferme une fenêtre, celle-ci cesse d’exister. Une fois qu’une fenêtre est fermée, elle ne peut pas être rouverte. Vous pouvez fermer une fenêtre à l’aide d’éléments de la zone non cliente, notamment :

  • L’élément Fermer du menu Système.
  • Appuyer sur ALT + F4.
  • Appuyer sur le bouton Fermer.
  • Appuyer sur Échap lorsqu’un bouton a la propriété IsCancel définie sur true sur une fenêtre modale.

Vous pouvez fournir des mécanismes supplémentaires à la zone cliente pour fermer une fenêtre, notamment :

  • un élément Quitter dans le menu Fichier, généralement pour les fenêtres d’application principales.
  • un élément Fermer dans le menu Fichier, généralement dans une fenêtre d’application secondaire.
  • un bouton Annuler, généralement dans une boîte de dialogue modale.
  • un bouton Fermer, généralement dans une boîte de dialogue non modale.

Pour fermer une fenêtre en réponse à l’un de ces mécanismes personnalisés, vous devez appeler la méthode Close. L’exemple suivant implémente la fermeture d’une fenêtre via l’élément Quitter du menu Fichier.

<Window x:Class="WindowsOverview.ClosingWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ClosingWindow" Height="450" Width="800">
    <StackPanel>
        <Menu>
            <MenuItem Header="_File">
                <MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
            </MenuItem>
        </Menu>
    </StackPanel>
</Window>

Le code suivant est le code-behind pour le code XAML.

using System.Windows;

namespace WindowsOverview
{
    public partial class ClosingWindow : Window
    {
        public ClosingWindow() =>
            InitializeComponent();

        private void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Close the current window
            this.Close();
        }
    }
}
Public Class ClosingWindow
    Private Sub fileExitMenuItem_Click(sender As Object, e As RoutedEventArgs)
        ' Close the current window
        Me.Close()
    End Sub
End Class

Remarque

Vous pouvez configurer une application pour qu’elle s’arrête automatiquement à la fermeture de la fenêtre d’application principale (consultez MainWindow) ou à la fermeture de la dernière fenêtre. Pour plus d’informations, consultez ShutdownMode.

Une fenêtre peut être fermée explicitement via des mécanismes fournis dans les zones clientes et non-clientes. Toutefois, une fenêtre peut également être fermée implicitement en fonction du comportement d’autres parties de l’application ou de Windows, notamment dans les cas suivants :

Important

Une fenêtre ne peut pas être rouverte après sa fermeture.

Annuler la fermeture de fenêtre

Lorsqu’une fenêtre se ferme, elle déclenche deux événements : Closing et Closed.

Closing est déclenché avant la fermeture de la fenêtre et fournit un mécanisme qui permet d’empêcher cette fermeture. Bien souvent, la fermeture d’une fenêtre est nécessaire si elle contient des données qui ont été modifiées. Dans cette situation, vous pouvez gérer l’événement Closing pour déterminer si les données sont modifiées et, dans ce cas, demander à l’utilisateur s’il souhaite poursuivre la fermeture de la fenêtre sans enregistrer les données ou annuler cette fermeture. L'exemple suivant décrit l'aspect de clé du traitement de Closing.

<Window x:Class="WindowsOverview.DataWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataWindow" Height="450" Width="800"
        Closing="Window_Closing">
    <Grid>
        <TextBox x:Name="documentTextBox" TextChanged="documentTextBox_TextChanged" />
    </Grid>
</Window>

Le code suivant est le code-behind pour le code XAML.

using System.Windows;
using System.Windows.Controls;

namespace WindowsOverview
{
    public partial class DataWindow : Window
    {
        private bool _isDataDirty;

        public DataWindow() =>
            InitializeComponent();

        private void documentTextBox_TextChanged(object sender, TextChangedEventArgs e) =>
            _isDataDirty = true;

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // If data is dirty, prompt user and ask for a response
            if (_isDataDirty)
            {
                var result = MessageBox.Show("Document has changed. Close without saving?",
                                             "Question",
                                             MessageBoxButton.YesNo);

                // User doesn't want to close, cancel closure
                if (result == MessageBoxResult.No)
                    e.Cancel = true;
            }
        }
    }
}
Public Class DataWindow

    Private _isDataDirty As Boolean

    Private Sub documentTextBox_TextChanged(sender As Object, e As TextChangedEventArgs)
        _isDataDirty = True
    End Sub

    Private Sub Window_Closing(sender As Object, e As ComponentModel.CancelEventArgs)

        ' If data is dirty, prompt user and ask for a response
        If _isDataDirty Then
            Dim result = MessageBox.Show("Document has changed. Close without saving?",
                                         "Question",
                                         MessageBoxButton.YesNo)

            ' User doesn't want to close, cancel closure
            If result = MessageBoxResult.No Then
                e.Cancel = True
            End If
        End If

    End Sub
End Class

Le gestionnaire d’événements Closing est passé un CancelEventArgs, qui implémente la propriété Cancel que vous avez définie sur true pour empêcher la fermeture d’une fenêtre.

Si Closing n’est pas gérée ou qu’elle est gérée mais non annulée, la fenêtre se ferme. Juste avant la fermeture d’une fenêtre, Closed est levée. À ce stade, il est impossible d’empêcher une fenêtre de se fermer.

Événements de la durée de vie d’une fenêtre

L’illustration suivante montre la séquence des événements principaux de la durée de vie d’une fenêtre :

Diagramme montrant les événements dans la durée de vie d’une fenêtre.

L’illustration suivante montre la séquence des principaux événements de la durée de vie d’une fenêtre affichée sans activation (ShowActivated a la valeur false avant l’affichage de la fenêtre) :

Diagramme montrant les événements dans la durée de vie d’une fenêtre sans activation.

Emplacement d’une fenêtre

Quand une fenêtre est ouverte, elle dispose d’un emplacement dans les dimensions x et y du Bureau. Cet emplacement peut être déterminé en inspectant les propriétés Left et Top, respectivement. Définissez ces propriétés pour changer l’emplacement de la fenêtre.

Vous pouvez également spécifier l’emplacement initial d’un Window lorsqu’il apparaît pour la première fois en définissant la propriété WindowStartupLocation avec l’une des valeurs d’énumération WindowStartupLocation suivantes :

Si l’emplacement de démarrage est spécifié en tant que Manual, et que les propriétés Left et Top n’ont pas été définies, Window demande au système d’exploitation qu’un emplacement s’affiche.

Fenêtres au premier plan et ordre de plan

Outre un emplacement dans les dimensions x et y, une fenêtre a également un emplacement dans la dimension z, qui détermine sa position verticale par rapport à d’autres fenêtres. Il s’agit de l’ordre de plan de la fenêtre. Il en existe deux types : l’ordre de plan normal et l’ordre de plan le plus haut. L’emplacement d’une fenêtre dans l’ordre de plan normal est déterminé par le fait qu’elle est active ou non. Par défaut, une fenêtre est située dans l’ordre de plan normal. L’emplacement d’une fenêtre dans l’ordre de plan le plus haut est également déterminé par le fait qu’elle est active ou non. De plus, les fenêtres dans l’ordre de plan le plus haut sont toujours situées au-dessus des fenêtres dans l’ordre de plan normal. Pour situer une fenêtre dans l’ordre de plan le plus haut, affectez à sa propriété Topmost la valeur true.

Dans chaque ordre de plan, la fenêtre active apparaît au-dessus de toutes les autres fenêtres du même ordre de plan.

Taille de la fenêtre

En plus d’avoir un emplacement sur le Bureau, une fenêtre a une taille déterminée par plusieurs propriétés, notamment diverses propriétés de largeur et de hauteur et SizeToContent.

MinWidth, Widthet MaxWidth sont utilisés pour gérer la plage de largeurs qu’une fenêtre peut avoir pendant sa durée de vie.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinWidth="300" Width="400" MaxWidth="500">
</Window>

La hauteur de fenêtre est gérée par MinHeight, Heightet MaxHeight.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinHeight="300" Height="400" MaxHeight="500">
</Window>

Comme les diverses valeurs de largeur et de hauteur spécifient chacune une plage, il est possible pour la largeur et la hauteur d’une fenêtre redimensionnable de se situer n’importe où dans la plage spécifiée pour la dimension respective. Pour détecter sa largeur et sa hauteur actuelles, inspectez ActualWidth et ActualHeight, respectivement.

Si vous souhaitez que la largeur et la hauteur de votre fenêtre correspondent à la taille du contenu de la fenêtre, utilisez la propriété SizeToContent, qui a les valeurs suivantes :

L’exemple suivant montre une fenêtre qui s’ajuste automatiquement en fonction de son contenu, verticalement et horizontalement, au moment où elle s’affiche pour la première fois.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    SizeToContent="WidthAndHeight">
</Window>

L’exemple suivant montre comment définir la propriété SizeToContent dans le code pour spécifier la façon dont une fenêtre se redimensionne afin de s’ajuster à son contenu.

// Manually alter window height and width
this.SizeToContent = SizeToContent.Manual;

// Automatically resize width relative to content
this.SizeToContent = SizeToContent.Width;

// Automatically resize height relative to content
this.SizeToContent = SizeToContent.Height;

// Automatically resize height and width relative to content
this.SizeToContent = SizeToContent.WidthAndHeight;
' Manually alter window height and width
Me.SizeToContent = SizeToContent.Manual

' Automatically resize width relative to content
Me.SizeToContent = SizeToContent.Width

' Automatically resize height relative to content
Me.SizeToContent = SizeToContent.Height

' Automatically resize height and width relative to content
Me.SizeToContent = SizeToContent.WidthAndHeight

Ordre de priorité des propriétés de dimensionnement

Pour l’essentiel, les diverses propriétés de dimensionnement d’une fenêtre se combinent pour définir la plage de largeur et de hauteur d’une fenêtre redimensionnable. Pour garantir la validité d’une plage, Window évalue les valeurs des propriétés de taille en fonction des ordres de priorité suivants.

Pour les propriétés de hauteur :

  1. FrameworkElement.MinHeight
  2. FrameworkElement.MaxHeight
  3. SizeToContent.Height / SizeToContent.WidthAndHeight
  4. FrameworkElement.Height

Pour les propriétés de largeur :

  1. FrameworkElement.MinWidth
  2. FrameworkElement.MaxWidth
  3. SizeToContent.Width / SizeToContent.WidthAndHeight
  4. FrameworkElement.Width

L’ordre de priorité permet également de déterminer la taille d’une fenêtre quand elle est agrandie, via la propriété WindowState.

Window state

Au cours de sa durée de vie, une fenêtre redimensionnable peut avoir trois états : normal, réduit et agrandi. L’état par défaut d’une fenêtre est l’état normal. Quand une fenêtre est dans cet état, l’utilisateur peut la déplacer et la redimensionner à l’aide d’une poignée de redimensionnement ou de la bordure, si elle est redimensionnable.

Quand une fenêtre est à l’état réduit, elle est réduite à son bouton de la barre des tâches si ShowInTaskbar a la valeur true. Sinon, elle est réduite à la plus petite taille possible et se place dans le coin inférieur gauche du Bureau. Aucun type de fenêtre réduite ne peut être redimensionné à l’aide d’une bordure ou d’une poignée de redimensionnement. Toutefois, une fenêtre réduite qui n’est pas affichée dans la barre des tâches peut être déplacée partout sur le Bureau.

Une fenêtre avec un état agrandi s’étend à la taille maximale qu’elle peut être, ce qui ne sera que aussi grand que ses propriétés MaxWidth, MaxHeightet SizeToContent le dictent. Comme pour une fenêtre réduite, vous ne pouvez pas redimensionner une fenêtre agrandie à l’aide d’une poignée de redimensionnement ou en faisant glisser sa bordure.

Remarque

Les valeurs des propriétés Top, Left, Widthet Height d’une fenêtre représentent toujours les valeurs de l’état normal, même lorsque la fenêtre est actuellement agrandie ou réduite.

L’état d’une fenêtre peut être configuré en définissant sa propriété WindowState, qui peut avoir l’une des valeurs d’énumération WindowState suivantes :

L’exemple suivant montre comment créer une fenêtre agrandie quand elle s’ouvre.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowState="Maximized">
</Window>

En règle générale, vous devez définir WindowState pour configurer l’état initial d’une fenêtre. Une fois qu’une fenêtre redimensionnable est affichée, les utilisateurs peuvent cliquer dans la barre de titre de la fenêtre sur les boutons de réduction, d’agrandissement et de restauration pour changer son état.

Apparence de la fenêtre

Vous pouvez changer l’apparence de la zone cliente d’une fenêtre en lui ajoutant un contenu spécifique, par exemple des boutons, des étiquettes et des zones de texte. Pour configurer la zone non cliente, Window fournit plusieurs propriétés, notamment Icon pour définir l’icône d’une fenêtre et Title pour définir son titre.

Vous pouvez également changer l’apparence et le comportement d’une bordure de zone non cliente en configurant le mode de redimensionnement d’une fenêtre, le style de fenêtre, ainsi que son affichage ou non sous forme de bouton dans la barre des tâches du Bureau.

Mode de redimensionnement

Selon la propriété WindowStyle, vous pouvez contrôler si et comment les utilisateurs redimensionnent la fenêtre. Le style de fenêtre affecte les éléments suivants :

  • Autoriser ou interdire le redimensionnement en faisant glisser la bordure de la fenêtre avec la souris.
  • Indique si les boutons Réduire, Agrandir et Fermer s’affichent dans la zone non cliente.
  • Indique si les boutons Réduire, Agrandir et Fermer sont activés.

Vous pouvez configurer comment une fenêtre est redimensionnée en définissant sa propriété ResizeMode, qui peut avoir l’une des valeurs d’énumération ResizeMode suivantes :

Comme avec WindowStyle, il est improbable que le mode de redimensionnement d’une fenêtre change pendant sa durée de vie, ce qui signifie que vous le définirez très probablement à partir du balisage XAML.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ResizeMode="CanResizeWithGrip">
</Window>

Notez que vous pouvez détecter si une fenêtre est agrandie, réduite ou restaurée en consultant la propriété WindowState.

Window style

La bordure exposée à partir de la zone non cliente d’une fenêtre convient à la plupart des applications. Toutefois, selon les circonstances, il arrive que d’autres types de bordure (voire aucune bordure) soient nécessaires, en fonction du type de fenêtre.

Pour contrôler le type de bordure d’une fenêtre, vous définissez sa propriété WindowStyle avec l’une des valeurs suivantes de l’énumération WindowStyle :

L’effet de l’application d’un style de fenêtre est illustré dans l’image suivante :

Capture d’écran montrant comment WindowStyle affecte une fenêtre dans WPF.

Notez que l’image ci-dessus n’affiche aucune différence notable entre SingleBorderWindow et ThreeDBorderWindow. De retour dans Windows XP, ThreeDBorderWindow a affecté la façon dont la fenêtre a été dessinée, en ajoutant une bordure 3D à la zone cliente. À compter de Windows 7, les différences entre les deux styles sont minimales.

Vous pouvez définir WindowStyle à l’aide du balisage XAML ou du code. Étant donné qu’il est peu probable qu’elle change pendant la durée de vie d’une fenêtre, vous la configurerez probablement à l’aide du balisage XAML.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowStyle="ToolWindow">
</Window>

Style de fenêtre non rectangulaire

Il existe également des situations où les styles de bordure que WindowStyle vous permet d’avoir ne sont pas suffisants. Par exemple, vous souhaitez créer une application avec une bordure non rectangulaire, comme celle du Microsoft Windows Media Player.

Prenons le cas de la fenêtre de bulle de commentaire représentée dans l’image suivante :

Capture d’écran d’une fenêtre WPF avec une zone clippée et une forme personnalisée.

Ce type de fenêtre peut être créé en définissant la propriété WindowStyle sur None, et en utilisant une prise en charge spéciale que Window a pour transparence.

<Window x:Class="WindowsOverview.ClippedWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ClippedWindow" SizeToContent="WidthAndHeight"
        WindowStyle="None" AllowsTransparency="True" Background="Transparent">
    <Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="20"/>
        </Grid.RowDefinitions>

        <Rectangle Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
        <Path Fill="White" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="15,-5.597,0,-0.003" Width="30" Grid.Row="1" Data="M22.166642,154.45381 L29.999666,187.66699 40.791059,154.54395"/>
        <Rectangle Fill="White" RadiusX="10" RadiusY="10" Margin="1"/>
        
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="25" Text="Greetings!" TextWrapping="Wrap" Margin="5,5,50,5"/>
        <Button HorizontalAlignment="Right" VerticalAlignment="Top" Background="Transparent" BorderBrush="{x:Null}" Foreground="Red" Content="❌" FontSize="15" />

        <Grid.Effect>
            <DropShadowEffect BlurRadius="10" ShadowDepth="3" Color="LightBlue"/>
        </Grid.Effect>
    </Grid>
</Window>

Cette combinaison de valeurs indique à la fenêtre de s’afficher de manière transparente. Dans cet état, les boutons d’ornement de la zone non cliente de la fenêtre ne peuvent pas être utilisés et vous devez fournir vos propres boutons.

Présence de la barre des tâches

L’apparence par défaut d’une fenêtre comprend un bouton de barre des tâches. Certains types de fenêtres n’ont pas de bouton de barre des tâches, comme les boîtes de message, les boîtes de dialogue ou les fenêtres avec la propriété WindowStyle définie sur ToolWindow. Vous pouvez contrôler si le bouton de barre des tâches d’une fenêtre s’affiche en définissant la propriété ShowInTaskbar (true par défaut).

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ShowInTaskbar="False">
</Window>

Autres types de fenêtre

NavigationWindow est une fenêtre conçue pour héberger du contenu navigable.

Les boîtes de dialogue sont des fenêtres souvent utilisées pour rassembler des informations fournies par un utilisateur afin d’exécuter une fonction. Par exemple, quand un utilisateur souhaite ouvrir un fichier, une application affiche la boîte de dialogue Ouvrir un fichier pour permettre à l’utilisateur d’indiquer le nom du fichier. Pour plus d’informations, consultez Vue d’ensemble des boîtes de dialogue.

Voir aussi