Bagikan melalui


Peristiwa masa pakai objek (WPF .NET)

Selama masa pakainya, semua objek dalam kode terkelola Microsoft .NET melalui tahap pembuatan, penggunaan, dan penghancuran . Windows Presentation Foundation (WPF) menyediakan pemberitahuan tentang tahapan ini, saat terjadi pada objek, dengan menaikkan peristiwa seumur hidup. Untuk elemen tingkat kerangka kerja WPF (objek visual), WPF mengimplementasikan Initializedperistiwa , , Loadeddan Unloaded seumur hidup. Pengembang dapat menggunakan peristiwa seumur hidup ini sebagai kait untuk operasi code-behind yang melibatkan elemen. Artikel ini menjelaskan peristiwa seumur hidup untuk objek visual, lalu memperkenalkan peristiwa seumur hidup lainnya yang secara khusus berlaku untuk elemen jendela, host navigasi, atau objek aplikasi.

Penting

Dokumentasi Panduan Desktop untuk .NET 7 dan .NET 6 sedang dibangun.

Prasyarat

Artikel ini mengasumsikan pengetahuan dasar tentang bagaimana tata letak elemen WPF dapat dikonsep sebagai pohon, dan bahwa Anda telah membaca gambaran umum peristiwa rute. Untuk mengikuti contoh dalam artikel ini, ini membantu jika Anda terbiasa dengan Extensible Application Markup Language (XAML) dan tahu cara menulis aplikasi WPF.

Peristiwa seumur hidup untuk objek visual

Elemen tingkat kerangka kerja WPF berasal dari FrameworkElement atau FrameworkContentElement. Peristiwa Initialized, , Loadeddan Unloaded seumur hidup umum untuk semua elemen tingkat kerangka kerja WPF. Contoh berikut menunjukkan pohon elemen yang terutama diimplementasikan dalam XAML. XAML mendefinisikan elemen induk Canvas yang berisi elemen berlapis, yang masing-masing menggunakan sintaks atribut XAML untuk melampirkan InitializedLoaded, , dan Unloaded penanganan aktivitas seumur hidup.

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

Salah satu elemen XAML adalah kontrol kustom, yang berasal dari kelas dasar yang menetapkan penanganan aktivitas seumur hidup di 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.

Output program menunjukkan urutan pemanggilan Initializedperistiwa , , Loadeddan Unloaded seumur hidup pada setiap objek pohon. Peristiwa tersebut dijelaskan di bagian berikut, dalam urutan dinaikkan pada setiap objek pohon.

Peristiwa seumur hidup yang diinisialisasi

Sistem peristiwa WPF meningkatkan Initialized peristiwa pada elemen:

  • Saat properti elemen diatur.
  • Sekitar saat yang sama objek diinisialisasi melalui panggilan ke konstruktornya.

Beberapa properti elemen, seperti Panel.Children, dapat berisi elemen turunan. Elemen induk tidak dapat melaporkan inisialisasi hingga elemen turunannya diinisialisasi. Jadi, nilai properti diatur dimulai dengan elemen yang paling berlapis dalam di pohon elemen, diikuti oleh elemen induk berturut-turut hingga akar aplikasi. Initialized Karena peristiwa terjadi ketika properti elemen diatur, peristiwa tersebut pertama kali dipanggil pada elemen yang paling dalam berlapis seperti yang didefinisikan dalam markup, diikuti oleh elemen induk berturut-turut hingga akar aplikasi. Ketika objek dibuat secara dinamis di code-behind, inisialisasinya mungkin tidak berurutan.

Sistem peristiwa WPF tidak menunggu semua elemen di pohon elemen diinisialisasi sebelum menaikkan Initialized peristiwa pada elemen. Jadi, ketika Anda menulis penanganan Initialized aktivitas untuk elemen apa pun, perlu diingat bahwa elemen di sekitarnya di pohon logis atau visual, terutama elemen induk, mungkin belum dibuat. Atau, variabel anggota dan pengikatan data mereka mungkin tidak diinisialisasi.

Catatan

Initialized Saat peristiwa dinaikkan pada elemen, penggunaan ekspresi elemen, seperti sumber daya dinamis atau pengikatan, akan tidak dievaluasi.

Peristiwa seumur hidup yang dimuat

Sistem peristiwa WPF meningkatkan Loaded peristiwa pada elemen:

  • Saat pohon logis yang berisi elemen selesai dan tersambung ke sumber presentasi. Sumber presentasi menyediakan handel jendela (HWND) dan permukaan penyajian.
  • Saat pengikatan data ke sumber lokal, seperti properti lain atau sumber data yang ditentukan langsung, selesai.
  • Setelah sistem tata letak menghitung semua nilai yang diperlukan untuk penyajian.
  • Sebelum penyajian terakhir.

Peristiwa Loaded tidak dimuat pada elemen apa pun di pohon elemen sampai semua elemen dalam pohon logis dimuat. Sistem peristiwa WPF pertama kali menaikkan Loaded peristiwa pada elemen akar pohon elemen, kemudian pada setiap elemen anak berturut-turut ke elemen yang paling bersarang paling dalam. Meskipun peristiwa ini mungkin menyerupai peristiwa terowongan yang dirutekan, Loaded peristiwa tidak membawa data peristiwa dari satu elemen ke elemen lainnya, sehingga menandai peristiwa seperti yang ditangani tidak berpengaruh.

Catatan

Sistem peristiwa WPF tidak dapat menjamin bahwa pengikatan data asinkron telah selesai sebelum Loaded peristiwa. Pengikatan data asinkron mengikat ke sumber eksternal atau dinamis.

Peristiwa seumur hidup yang tidak dimuat

Sistem peristiwa WPF meningkatkan Unloaded peristiwa pada elemen:

  • Pada penghapusan sumber presentasinya, atau
  • Pada penghapusan induk visualnya.

Sistem peristiwa WPF pertama kali menaikkan Unloaded peristiwa pada elemen akar pohon elemen, kemudian pada setiap elemen anak berturut-turut ke elemen yang paling bersarang paling dalam. Meskipun peristiwa ini mungkin menyerupai peristiwa terowongan yang dirutekan, Unloaded peristiwa tidak menyebarluaskan data peristiwa dari elemen ke elemen, sehingga menandai peristiwa seperti yang ditangani tidak berpengaruh.

Unloaded Ketika peristiwa dinaikkan pada elemen, itu adalah elemen induk atau elemen apa pun yang lebih tinggi di pohon logis atau visual mungkin sudah tidak diatur. Unset berarti bahwa pengikatan data, referensi sumber daya, dan gaya elemen tidak lagi diatur ke nilai run-time normal atau terakhir yang diketahui.

Peristiwa seumur hidup lainnya

Dari perspektif peristiwa seumur hidup, ada empat jenis utama objek WPF: elemen secara umum, elemen jendela, host navigasi, dan objek aplikasi. Peristiwa Initialized, , Loadeddan Unloaded seumur hidup berlaku untuk semua elemen tingkat kerangka kerja. Peristiwa seumur hidup lainnya secara khusus berlaku untuk elemen jendela, host navigasi, atau objek aplikasi. Untuk informasi tentang peristiwa seumur hidup lainnya, lihat:

Baca juga