Události životnosti objektů (WPF .NET)
Během své životnosti procházejí všechny objekty ve spravovaném kódu Microsoft .NET fázemi vytváření, používání a zničení . Windows Presentation Foundation (WPF) poskytuje oznámení o těchto fázích, ke kterým dochází u objektu, vyvoláním událostí životnosti. Pro elementy na úrovni architektury WPF (vizuální objekty) WPF implementuje Initializedudálosti , Loadeda Unloaded životnosti. Vývojáři můžou tyto události životnosti používat jako hooky pro operace za kódem, které zahrnují prvky. Tento článek popisuje události životnosti pro vizuální objekty a pak zavádí další události životnosti, které se konkrétně vztahují na prvky oken, hostitele navigace nebo objekty aplikace.
Požadavky
Tento článek předpokládá základní znalosti o tom, jak lze rozložení elementu WPF konceptualizovat jako strom a že jste si přečetli přehled směrovaných událostí. Pokud chcete postupovat podle příkladů v tomto článku, pomůže vám to, pokud znáte jazyk XAML (Extensible Application Markup Language) a víte, jak psát aplikace WPF.
Události životnosti pro objekty vizuálu
Prvky na úrovni architektury WPF jsou odvozeny z FrameworkElement nebo FrameworkContentElement. Události Initialized, Loadeda Unloaded životnosti jsou společné pro všechny prvky architektury WPF. Následující příklad ukazuje strom elementu, který je primárně implementován v XAML. XAML definuje nadřazený Canvas prvek, který obsahuje vnořené elementy, které každý používá syntaxi atributu XAML pro připojení Initialized
, Loaded
a Unloaded
obslužné rutiny událostí životnosti.
<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>
Jedním z elementů XAML je vlastní ovládací prvek, který je odvozen od základní třídy, která přiřazuje obslužné rutiny události životnosti v kódu za sebou.
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.
Výstup programu zobrazuje pořadí vyvolání Initialized
událostí , Loaded
a Unloaded
životnosti u každého objektu stromu. Tyto události jsou popsány v následujících částech v pořadí, v jakém jsou vyvolány u každého objektu stromu.
Inicializovaná událost životnosti
Systém událostí WPF vyvolá událost u elementu Initialized :
- Když jsou nastaveny vlastnosti elementu.
- Přibližně ve stejnou dobu, kdy je objekt inicializován voláním jeho konstruktoru.
Některé vlastnosti elementu, například Panel.Children, mohou obsahovat podřízené prvky. Nadřazené prvky nemůžou inicializovat sestavy, dokud nebudou inicializovány jejich podřízené prvky. Hodnoty vlastností se tedy nastavují od nejrozsáhlejších vnořených elementů ve stromu elementů a následné nadřazené prvky až do kořenového adresáře aplikace. Vzhledem k tomu, že Initialized
událost nastane, když jsou vlastnosti elementu nastaveny, tato událost je nejprve vyvolána na nejmíň vnořené elementy definované v kódu, následované následnými nadřazenými prvky až do kořenového adresáře aplikace. Pokud se objekty dynamicky vytvářejí v kódu za sebou, může být jejich inicializace mimo posloupnost.
Systém událostí WPF nečeká na inicializaci všech prvků ve stromu elementu Initialized
před vyvolání události na elementu. Takže když napíšete obslužnou rutinu Initialized
události pro libovolný prvek, mějte na paměti, že okolní prvky v logickém nebo vizuálním stromu, zejména nadřazené prvky, nebyly vytvořeny. Nebo mohou být jejich členské proměnné a datové vazby neinicializovány.
Poznámka:
Initialized
Když je událost vyvolána u elementu, výrazy elementu, jako jsou dynamické prostředky nebo vazby, budou nehodnocené.
Načtená událost životnosti
Systém událostí WPF vyvolá událost u elementu Loaded :
- Pokud je logický strom obsahující prvek dokončen a připojen ke zdroji prezentace. Zdroj prezentace poskytuje úchyt okna (HWND) a vykreslovací plochu.
- Když jsou datové vazby k místním zdrojům, například k jiným vlastnostem nebo přímo definovaným zdrojům dat, dokončeny.
- Jakmile systém rozložení vypočítá všechny potřebné hodnoty pro vykreslování.
- Před konečným vykreslením.
Událost Loaded
není vyvolána u žádného prvku ve stromu elementu, dokud nebudou načteny všechny prvky v rámci logického stromu . Systém událostí WPF nejprve vyvolá Loaded
událost na kořenovém prvku stromu elementů a pak na každém po sobě jdoucím podřízeného elementu až po nejhrozšířenější vnořené elementy. I když tato událost může vypadat podobně jako tunelová událost, Loaded
událost nepřenáší data událostí z jednoho prvku do druhého, takže označení události jako zpracovávané nemá žádný vliv.
Poznámka:
Systém událostí WPF nemůže zaručit, že se před Loaded
událostí dokončily asynchronní datové vazby. Asynchronní datové vazby se sváže s externími nebo dynamickými zdroji.
Událost unloaded lifetime
Systém událostí WPF vyvolá událost u elementu Unloaded :
- Při odstranění jejího zdroje prezentace nebo
- Při odebrání nadřazeného vizuálu
Systém událostí WPF nejprve vyvolá Unloaded
událost na kořenovém prvku stromu elementů a pak na každém po sobě jdoucím podřízeného elementu až po nejhrozšířenější vnořené elementy. I když se tato událost může podobat trasované události tunelu , Unloaded
událost nerozšířuje data událostí z elementu do elementu, takže označení události jako zpracovávané nemá žádný vliv.
Unloaded
Když je událost vyvolána u elementu, je to nadřazený prvek nebo jakýkoli prvek vyšší v logickém nebo vizuálním stromu již pravděpodobně nebyl nastaven. Zrušením nastavení znamená, že datové vazby elementu, odkazy na prostředky a styly už nejsou nastavené na jejich normální nebo poslední známou hodnotu za běhu.
Jiné události životnosti
Z hlediska událostí životnosti existují čtyři hlavní typy objektů WPF: prvky obecně, prvky okna, hostitele navigace a objekty aplikace. Události Initialized, Loadeda Unloaded životnosti se vztahují na všechny prvky na úrovni architektury. Jiné události životnosti se konkrétně vztahují na prvky okna, hostitele navigace nebo objekty aplikace. Informace o těchto dalších událostech životnosti najdete tady:
- Přehled správy aplikací pro Application objekty
- Přehled oken WPF pro Window prvky
- Přehled navigace pro Page, NavigationWindowa Frame prvky.
Viz také
.NET Desktop feedback