Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Pendant leur durée de vie, tous les objets du code managé Microsoft .NET passent par des phases de création, d’utilisation et de destruction . Windows Presentation Foundation (WPF) fournit une notification de ces étapes, car elles se produisent sur un objet, en générant des événements de durée de vie. Pour les éléments du niveau framework WPF (objets visuels), WPF implémente Initialized, Loaded, et Unloaded en tant qu'événements de durée de vie. Les développeurs peuvent utiliser ces événements de durée de vie comme points d'attache pour les opérations en arrière-plan du code qui impliquent des éléments. Cet article décrit les événements de durée de vie des objets visuels, puis présente d’autres événements de durée de vie qui s’appliquent spécifiquement aux éléments de fenêtre, aux hôtes de navigation ou aux objets d’application.
Conditions préalables
Cet article suppose une connaissance de base de la façon dont la disposition des éléments WPF peut être conceptualisée en tant qu’arborescence et que vous avez lu la vue d’ensemble des événements routés. Pour suivre les exemples de cet article, il vous aide à connaître le langage XAML (Extensible Application Markup Language) et à savoir comment écrire des applications WPF.
Événements de cycle de vie pour les objets visuels
Les éléments du framework WPF dérivent de FrameworkElement ou de FrameworkContentElement. Les événements de cycle de vie Initialized, Loaded et Unloaded sont communs à tous les éléments de niveau framework WPF. L’exemple suivant montre une arborescence d’éléments qui est principalement implémentée en XAML. Le code XAML définit un élément parent Canvas qui contient des éléments imbriqués, chacun utilisant une syntaxe d’attribut XAML pour attacher des gestionnaires d’événements liés à la durée de vie à Initialized, Loaded et Unloaded.
<Canvas x:Name="canvas">
<StackPanel x:Name="outerStackPanel" Initialized="InitHandler" Loaded="LoadHandler" Unloaded="UnloadHandler">
<custom:ComponentWrapper x:Name="componentWrapper" Initialized="InitHandler" Loaded="LoadHandler" Unloaded="UnloadHandler">
<TextBox Name="textBox1" Initialized="InitHandler" Loaded="LoadHandler" Unloaded="UnloadHandler" />
<TextBox Name="textBox2" Initialized="InitHandler" Loaded="LoadHandler" Unloaded="UnloadHandler" />
</custom:ComponentWrapper>
</StackPanel>
<Button Content="Remove canvas child elements" Click="Button_Click"/>
</Canvas>
L'un des éléments XAML est un contrôle personnalisé, qui dérive d'une classe de base attribuant des gestionnaires d'événements de cycle de vie dans le code-behind.
public partial class MainWindow : Window
{
public MainWindow() => InitializeComponent();
// Handler for the Initialized lifetime event (attached in XAML).
private void InitHandler(object sender, System.EventArgs e) =>
Debug.WriteLine($"Initialized event on {((FrameworkElement)sender).Name}.");
// Handler for the Loaded lifetime event (attached in XAML).
private void LoadHandler(object sender, RoutedEventArgs e) =>
Debug.WriteLine($"Loaded event on {((FrameworkElement)sender).Name}.");
// Handler for the Unloaded lifetime event (attached in XAML).
private void UnloadHandler(object sender, RoutedEventArgs e) =>
Debug.WriteLine($"Unloaded event on {((FrameworkElement)sender).Name}.");
// Remove nested controls.
private void Button_Click(object sender, RoutedEventArgs e) =>
canvas.Children.Clear();
}
// Custom control.
public class ComponentWrapper : ComponentWrapperBase { }
// Custom base control.
public class ComponentWrapperBase : StackPanel
{
public ComponentWrapperBase()
{
// Assign handler for the Initialized lifetime event (attached in code-behind).
Initialized += (object sender, System.EventArgs e) =>
Debug.WriteLine($"Initialized event on componentWrapperBase.");
// Assign handler for the Loaded lifetime event (attached in code-behind).
Loaded += (object sender, RoutedEventArgs e) =>
Debug.WriteLine($"Loaded event on componentWrapperBase.");
// Assign handler for the Unloaded lifetime event (attached in code-behind).
Unloaded += (object sender, RoutedEventArgs e) =>
Debug.WriteLine($"Unloaded event on componentWrapperBase.");
}
}
/* Output:
Initialized event on textBox1.
Initialized event on textBox2.
Initialized event on componentWrapperBase.
Initialized event on componentWrapper.
Initialized event on outerStackPanel.
Loaded event on outerStackPanel.
Loaded event on componentWrapperBase.
Loaded event on componentWrapper.
Loaded event on textBox1.
Loaded event on textBox2.
Unloaded event on outerStackPanel.
Unloaded event on componentWrapperBase.
Unloaded event on componentWrapper.
Unloaded event on textBox1.
Unloaded event on textBox2.
*/
Partial Public Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
' Handler for the Initialized lifetime event (attached in XAML).
Private Sub InitHandler(sender As Object, e As EventArgs)
Debug.WriteLine($"Initialized event on {CType(sender, FrameworkElement).Name}.")
End Sub
' Handler for the Loaded lifetime event (attached in XAML).
Private Sub LoadHandler(sender As Object, e As RoutedEventArgs)
Debug.WriteLine($"Loaded event on {CType(sender, FrameworkElement).Name}.")
End Sub
' Handler for the Unloaded lifetime event (attached in XAML).
Private Sub UnloadHandler(sender As Object, e As RoutedEventArgs)
Debug.WriteLine($"Unloaded event on {CType(sender, FrameworkElement).Name}.")
End Sub
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
' Remove nested controls.
canvas.Children.Clear()
End Sub
End Class
' Custom control.
Public Class ComponentWrapper
Inherits ComponentWrapperBase
End Class
' Custom base control.
Public Class ComponentWrapperBase
Inherits StackPanel
Public Sub New()
' Attach handlers for the lifetime events.
AddHandler Initialized, AddressOf InitHandler
AddHandler Loaded, AddressOf LoadHandler
AddHandler Unloaded, AddressOf UnloadHandler
End Sub
' Handler for the Initialized lifetime event (attached in code-behind).
Private Sub InitHandler(sender As Object, e As EventArgs)
Debug.WriteLine("Initialized event on componentWrapperBase.")
End Sub
' Handler for the Loaded lifetime event (attached in code-behind).
Private Sub LoadHandler(sender As Object, e As RoutedEventArgs)
Debug.WriteLine("Loaded event on componentWrapperBase.")
End Sub
' Handler for the Unloaded lifetime event (attached in code-behind).
Private Sub UnloadHandler(sender As Object, e As RoutedEventArgs)
Debug.WriteLine("Unloaded event on componentWrapperBase.")
End Sub
End Class
'Output:
'Initialized event on textBox1.
'Initialized event on textBox2.
'Initialized event on componentWrapperBase.
'Initialized event on componentWrapper.
'Initialized event on outerStackPanel.
'Loaded event on outerStackPanel.
'Loaded event on componentWrapperBase.
'Loaded event on componentWrapper.
'Loaded event on textBox1.
'Loaded event on textBox2.
'Unloaded event on outerStackPanel.
'Unloaded event on componentWrapperBase.
'Unloaded event on componentWrapper.
'Unloaded event on textBox1.
'Unloaded event on textBox2.
La sortie du programme montre l'ordre d'appel des événements du cycle de vie Initialized, Loaded et Unloaded pour chaque objet de l'arborescence. Ces événements sont décrits dans les sections suivantes, dans l’ordre dans lequel ils sont déclenchés sur chaque objet d’arborescence.
Événement de durée de vie initialisé
Le système d’événements WPF déclenche l’événement Initialized sur un élément :
- Lorsque les propriétés de l’élément sont définies.
- En même temps que l’objet est initialisé par le biais d’un appel à son constructeur.
Certaines propriétés d’élément, telles que Panel.Children, peuvent contenir des éléments enfants. Les éléments parents ne peuvent pas signaler l’initialisation tant que leurs éléments enfants ne sont pas initialisés. Par conséquent, les valeurs de propriété sont définies à partir des éléments imbriqués les plus profondément dans une arborescence d’éléments, suivis d’éléments parents successifs jusqu’à la racine de l’application. Étant donné que l’événement Initialized se produit lorsque les propriétés d’un élément sont définies, cet événement est d’abord appelé sur les éléments imbriqués les plus profondément imbriqués tels que définis dans le balisage, suivis d’éléments parents successifs jusqu’à la racine de l’application. Lorsque les objets sont créés dynamiquement dans le code-behind, leur initialisation peut être hors séquence.
Le système d’événements WPF n’attend pas que tous les éléments d’une arborescence d’éléments soient initialisés avant de déclencher l’événement Initialized sur un élément. Par conséquent, lorsque vous écrivez un gestionnaire d’événements Initialized pour n’importe quel élément, gardez à l’esprit que les éléments environnants dans l’arborescence logique ou visuelle, en particulier les éléments parents, n’ont peut-être pas été créés. Ou bien, leurs variables membres et liaisons de données peuvent être non initialisées.
Remarque
Lorsque l’événement Initialized est déclenché sur un élément, les utilisations de l’expression de l’élément, telles que les ressources dynamiques ou la liaison, sont non évaluées.
Événement de cycle de vie chargé
Le système d’événements WPF déclenche l’événement Loaded sur un élément :
- Lorsque l’arborescence logique qui contient l’élément est terminée et connectée à une source de présentation. La source de présentation fournit le handle de fenêtre (HWND) et la surface de rendu.
- Lorsque la liaison de données à des sources locales, telles que d’autres propriétés ou sources de données directement définies, est terminée.
- Une fois que le système de disposition a calculé toutes les valeurs nécessaires pour le rendu.
- Avant le rendu final.
L’événement Loaded n’est déclenché sur aucun élément d’une arborescence d’éléments tant que tous les éléments de l’arborescence logique ne sont pas chargés. Le système d’événements WPF déclenche d’abord l’événement Loaded sur l’élément racine d’une arborescence d’éléments, puis sur chaque élément enfant successif jusqu’aux éléments imbriqués les plus profondément imbriqués. Bien que cet événement ressemble à un événement routé en tunneling, l’événement Loaded ne transporte pas les données de l’événement d’un élément à un autre, par conséquent, le marquage de l'événement comme traité n’a aucun effet.
Remarque
Le système d’événements WPF ne peut pas garantir que les liaisons de données asynchrones sont terminées avant l’événement Loaded . Les liaisons de données asynchrones sont liées à des sources externes ou dynamiques.
Événement de fin de cycle de vie
Le système d’événements WPF déclenche l’événement Unloaded sur un élément :
- Lors de la suppression de sa source de présentation, ou
- Lors de la suppression de son parent visuel.
Le système d’événements WPF déclenche d’abord l’événement Unloaded sur l’élément racine d’une arborescence d’éléments, puis sur chaque élément enfant successif jusqu’aux éléments imbriqués les plus profondément imbriqués. Bien que cet événement ressemble à un événement routé de tunneling, l’événement Unloaded ne propage pas les données de l’événement d’un élément à l’autre, donc marquer l’événement comme géré n’a aucun effet.
Lorsque l’événement Unloaded est déclenché sur un élément, son élément parent ou tout élément supérieur dans l’arborescence logique ou visuelle peut avoir déjà été réinitialisé. Unset signifie que les liaisons de données, les références de ressources et les styles d’un élément ne sont plus assignés à leur valeur normale ou à la dernière valeur attribuée lors de l'exécution.
Autres événements de vie
Du point de vue des événements de durée de vie, il existe quatre types principaux d’objets WPF : éléments en général, éléments de fenêtre, hôtes de navigation et objets d’application. Les événements de durée de vie Initialized, Loaded, et Unloaded s'appliquent à tous les éléments au niveau de l'infrastructure. D’autres événements de durée de vie s’appliquent spécifiquement aux éléments de fenêtre, aux hôtes de navigation ou aux objets d’application. Pour plus d’informations sur ces autres événements marquants de la vie, consultez :
- Vue d’ensemble de la gestion des applications
- Vue d’ensemble des fenêtres WPF pour les éléments Window.
- Vue d’ensemble de la navigation
Voir aussi
.NET Desktop feedback