Nyelv

Objektum-élettartam események

A Microsoft .NET által felügyelt kód összes objektuma az élettartamuk alatt végighalad a létrehozás, a használat és a megsemmisítés fázisán. A Windows Presentation Foundation (WPF) értesítést küld ezekről a szakaszokról, amint azok egy objektumon történnek, élettartam-események növelésével. A WPF keretrendszerszintű elemei (vizuális objektumok) esetében a WPF implementálja az , Initializedés Loaded az Unloadedélettartam eseményeit. A fejlesztők ezeket az élettartam-eseményeket horogként használhatják az elemeket tartalmazó kód mögötti műveletekhez. Ez a cikk a vizuális objektumok élettartam-eseményeit ismerteti, majd az ablakelemekre, navigációs gazdagépekre vagy alkalmazásobjektumokra vonatkozó egyéb élettartam-eseményeket mutat be.

Előfeltételek

Ez a cikk alapszintű ismereteket feltételez arról, hogy a WPF-elemelrendezés hogyan fogható fel faként, és hogy elolvasta az irányított események áttekintését. A cikkben szereplő példák követéséhez segít, ha ismeri az Extensible Application Markup Language (XAML) nyelvet, és ismeri a WPF-alkalmazások írásának módját.

Vizualizációs objektumok élettartam-eseményei

A WPF keretrendszerszintű elemei FrameworkElement vagy FrameworkContentElement származnak. A Initialized, Loadedés Unloaded az élettartam eseményei minden WPF-keretrendszerszintű elemre jellemzőek. Az alábbi példa egy elsősorban XAML-ben implementált elemfát mutat be. Az XAML olyan szülőelemet Canvas határoz meg, amely beágyazott elemeket tartalmaz, amelyek mindegyike XAML attribútumszintaxissal csatolja Initializedaz , Loadedés Unloaded az élettartam eseménykezelőit.

<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>

Az XAML-elemek egyike egy egyéni vezérlő, amely egy olyan alaposztályból származik, amely az élettartam eseménykezelőit rendeli hozzá a kód mögé.

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.

A program kimenete az egyes faobjektumok meghívási és élettartam-eseményeinek InitializedLoadedUnloaded sorrendjét jeleníti meg. Ezeket az eseményeket a következő szakaszok ismertetik, az események egyes faobjektumokon való bekövetkezésének sorrendjében.

Inicializált élettartam-esemény

A WPF eseményrendszer egy elemen emeli ki az Initialized eseményt:

  • Ha az elem tulajdonságai be vannak állítva.
  • Nagyjából ugyanabban az időben, amikor az objektum inicializálódik a konstruktor hívásával.

Egyes elemtulajdonságok, például Panel.Children, tartalmazhatnak gyermekelemeket. A szülőelemek csak a gyermekelemek inicializálása után jelenthetik az inicializálást. A tulajdonságértékek tehát az elemfa legmélyebb beágyazott elemével kezdődnek, majd egymást követő szülőelemek követik az alkalmazásgyökérig. Mivel az Initialized esemény akkor fordul elő, amikor egy elem tulajdonságai be vannak állítva, a rendszer először a korrektúra által definiált legmélyebb beágyazott elem(ek)en hívja meg az eseményt, majd egymást követő szülőelemeket az alkalmazásgyökérig. Ha az objektumok dinamikusan jönnek létre kód mögött, előfordulhat, hogy az inicializálásuk nem sorozatos.

A WPF eseményrendszer nem várja meg, hogy az elemfa összes eleme inicializálva legyen, mielőtt az Initialized eseményt egy elemre emeli. Ezért amikor egy eseménykezelőt Initialized ír bármely elemhez, ne feledje, hogy a logikai vagy vizuális fa környező elemei, különösen a szülőelemek, lehet, hogy még nem lettek létrehozva. Vagy előfordulhat, hogy a tagváltozók és adatkötések nincsenek inicializálva.

Megjegyzés:

Amikor az Initialized esemény egy elemen történik, az elem kifejezéshasználatai( például dinamikus erőforrások vagy kötések) nem lesznek értékelve.

Betöltött élettartam-esemény

A WPF eseményrendszer egy elemen emeli ki az Loaded eseményt:

  • Ha az elemet tartalmazó logikai fa elkészült, és egy bemutatóforráshoz csatlakozik. ** A prezentáció forrása biztosítja az ablakkezelőt (HWND) és a renderelési felületet.
  • Ha a helyi forrásokhoz, például más tulajdonságokhoz vagy közvetlenül definiált adatforrásokhoz való adatkötés befejeződött.
  • Miután az elrendezési rendszer kiszámította a rendereléshez szükséges összes értéket.
  • A végleges megjelenítés előtt.

Az Loaded esemény az elemfa egyik elemére sem kerül fel, amíg a logikai faösszes eleme be nem töltődik. A WPF eseményrendszer először egy Loaded elemfa gyökérelemén, majd minden egymást követő gyermekelemen a legmélyebb beágyazott elem(ek) felé emeli az eseményt. Bár ez az esemény hasonlíthat egy csatornázott irányított eseményre, az Loaded esemény nem hordoz eseményadatokat egyik elemről a másikra, ezért az esemény kezeltként való megjelölésének nincs hatása.

Megjegyzés:

A WPF eseményrendszer nem tudja garantálni, hogy az aszinkron adatkötések befejeződtek az Loaded esemény előtt. Az aszinkron adatkötések külső vagy dinamikus forrásokhoz kötődnek.

A tehermentesített élettartam esemény

A WPF eseményrendszer egy elemen emeli ki az Unloaded eseményt:

  • A bemutató forrásának eltávolítása esetén, vagy
  • A vizuális szülő eltávolítása után.

A WPF eseményrendszer először egy Unloaded elemfa gyökérelemén, majd minden egymást követő gyermekelemen a legmélyebb beágyazott elem(ek) felé emeli az eseményt. Annak ellenére, hogy ez az esemény hasonlíthat egy lefúrásra irányított eseményre, az Unloaded esemény nem propagálja az eseményadatokat elemről elemre, így az esemény kezeltként való megjelölésének nincs hatása.

Ha az Unloaded eseményt egy elemen emelik ki, előfordulhat, hogy az elem szülőeleme vagy a logikai vagy vizualizációs fa bármely magasabb eleme már nincs megadva. A kikapcsolás azt jelenti, hogy egy elem adatkötései, erőforrás-hivatkozásai és stílusai már nem az alapértelmezett vagy az utoljára ismert futásidejű értékre vannak beállítva.

Egyéb élet események

Az élettartam-események szempontjából a WPF-objektumok négy fő típusa létezik: az elemek általában véve, az ablakelemek, a navigációs hostok és az alkalmazásobjektumok. A Initialized, Loadedés Unloaded az élettartam események minden keretrendszerszintű elemre vonatkoznak. Az egyéb élettartam-események kifejezetten az ablakelemekre, navigációs gazdagépekre vagy alkalmazásobjektumokra vonatkoznak. A többi élettartam-eseményről további információt a következő témakörben talál:

Lásd még