Bagikan melalui


Gambaran umum peristiwa terlampir

Extensible Application Markup Language (XAML) mendefinisikan komponen bahasa dan jenis peristiwa yang disebut peristiwa terlampir . Peristiwa terlampir dapat digunakan untuk menentukan peristiwa baru yang dirutekan di kelas non-elemen dan menaikkan peristiwa tersebut pada elemen apa pun di pohon Anda. Untuk melakukannya, Anda harus mendaftarkan peristiwa terlampir sebagai peristiwa yang dirutekan dan menyediakan kode pendukung tertentu yang mendukung fungsionalitas peristiwa terlampir. Karena event yang ditempelkan didaftarkan sebagai event yang dirutekan, ketika dipicu pada elemen, event tersebut menyebar melalui pohon elemen.

Prasyarat

Artikel ini mengasumsikan pengetahuan dasar tentang peristiwa yang dirutekan Windows Presentation Foundation (WPF), dan bahwa Anda telah membaca gambaran umum peristiwa rute dan XAML di WPF. Untuk mengikuti contoh dalam artikel ini, ini membantu jika Anda terbiasa dengan XAML dan tahu cara menulis aplikasi WPF.

Sintaks peristiwa terlampir

Dalam sintaks XAML, peristiwa terlampir ditentukan oleh nama peristiwanya dan jenis pemiliknya, dalam bentuk <owner type>.<event name>. Karena nama event dikaitkan dengan nama jenis pemiliknya, sintaksis memungkinkan event dilampirkan ke setiap elemen yang dapat diinstansiasi. Sintaks ini juga berlaku untuk handler untuk peristiwa rute reguler yang melekat pada elemen arbitrer di sepanjang rute peristiwa.

Sintaks atribut XAML berikut melampirkan handler AquariumFilter_Clean untuk peristiwa terlampir AquariumFilter.Clean ke elemen aquarium1:

<aqua:Aquarium x:Name="aquarium1" Height="300" Width="400" aqua:AquariumFilter.Clean="AquariumFilter_Clean"/>

Dalam contoh ini, awalan aqua: diperlukan karena kelas AquariumFilter dan Aquarium ada di namespace dan assembly runtime bahasa umum (CLR) yang berbeda.

Anda juga dapat melampirkan handler untuk peristiwa terlampir dalam kode di belakang. Untuk melakukannya, panggil metode AddHandler pada objek dimana handler harus dilampirkan dan berikan ID peristiwa serta handler sebagai parameter ke metode tersebut.

Cara WPF mengimplementasikan peristiwa terlampir (attached events)

Event terlampir WPF diimplementasikan sebagai peristiwa yang dirutekan dan didukung oleh kolom RoutedEvent. Akibatnya, peristiwa terlampir menyebar melalui pohon elemen setelah dinaikkan. Umumnya, objek yang menaikkan peristiwa terlampir, yang dikenal sebagai sumber peristiwa, adalah sistem atau sumber layanan. Sumber sistem atau layanan bukan bagian langsung dari pohon elemen. Untuk peristiwa terlampir lainnya, sumber peristiwa mungkin merupakan elemen di pohon, seperti komponen dalam kontrol komposit.

Skenario peristiwa terlampir

Di WPF, event terlampir digunakan di area fitur tertentu di mana terdapat abstraksi pada tingkat layanan. Misalnya, WPF menggunakan peristiwa terlampir yang diaktifkan oleh kelas Mouse atau Validation statis. Kelas yang berinteraksi dengan atau menggunakan layanan dapat berinteraksi dengan peristiwa menggunakan sintaks peristiwa terlampir, atau menampilkan peristiwa terlampir sebagai peristiwa yang dirutekan. Opsi terakhir adalah bagian dari bagaimana kelas dapat mengintegrasikan kemampuan layanan.

Sistem input WPF menggunakan peristiwa terlampir secara ekstensif. Namun, hampir semua peristiwa terlampir tersebut muncul sebagai peristiwa rute yang tidak terpasang yang setara melalui elemen dasar. Setiap peristiwa input yang dirutekan adalah anggota kelas elemen dasar dan didukung dengan "pembungkus" peristiwa CLR. Anda jarang menggunakan atau menangani peristiwa terlampir secara langsung. Misalnya, lebih mudah untuk menangani peristiwa Mouse.MouseDown terlampir yang mendasar pada UIElement melalui peristiwa yang dirutekan UIElement.MouseDown yang setara daripada dengan menggunakan sintaks peristiwa terlampir di XAML atau code-behind.

Peristiwa terlampir melayani tujuan arsitektur dengan mengaktifkan perluasan perangkat input di masa mendatang. Misalnya, perangkat input baru hanya perlu mengaktifkan Mouse.MouseDown untuk mensimulasikan input mouse, dan tidak perlu menggunakan turunan dari Mouse untuk melakukannya. Skenario itu melibatkan penanganan kode peristiwa, karena penanganan XAML dari peristiwa yang terlampir tidak akan relevan.

Menangani acara yang terlampir

Proses untuk pengkodan dan penanganan peristiwa terlampir pada dasarnya sama dengan untuk peristiwa rute yang tidak terpasang.

Seperti disebutkan sebelumnya, peristiwa terlampir WPF yang ada biasanya tidak dimaksudkan untuk ditangani langsung di WPF. Lebih sering, tujuan peristiwa terlampir adalah untuk mengaktifkan elemen dalam kontrol komposit untuk melaporkan statusnya ke elemen induk dalam kontrol. Dalam skenario itu, peristiwa dipicu dalam kode dan bergantung pada penanganan oleh kelas induk yang relevan. Misalnya, item dalam Selector diharapkan untuk memicu kejadian terlampir Selected, yang kemudian ditangani oleh kelas Selector. Kelas Selector berpotensi mengonversi peristiwa Selected menjadi peristiwa SelectionChanged dirutekan. Untuk informasi selengkapnya tentang event yang dirutekan dan penanganan kelas, lihat Menandai event yang dirutekan sebagai telah ditangani, dan penanganan kelas.

Menentukan peristiwa terlampir kustom

Jika Anda berasal dari kelas dasar WPF umum, Anda dapat mengimplementasikan peristiwa terlampir kustom dengan menyertakan dua metode aksesor di kelas Anda. Metode tersebut adalah:

  • Tambahkan nama peristiwa<>metode Handler, dengan parameter pertama yang merupakan elemen tempat penanganan aktivitas dilampirkan, dan parameter kedua yang merupakan penanganan aktivitas untuk ditambahkan. Metode harus berupa public dan static, tanpa nilai pengembalian. Metode ini memanggil metode kelas dasar AddHandler, meneruskan peristiwa yang dirutekan dan pengendali sebagai argumen. Metode ini mendukung sintaks atribut XAML untuk melampirkan penanganan aktivitas ke elemen. Metode ini juga memungkinkan akses kode ke penyimpanan penanganan aktivitas untuk peristiwa terlampir.

  • Hapus nama peristiwa<>metode Handler, dengan parameter pertama yang merupakan elemen tempat penanganan aktivitas dilampirkan, dan parameter kedua yang merupakan penanganan aktivitas yang akan dihapus. Metode harus berupa public dan static, tanpa nilai pengembalian. Metode ini memanggil metode kelas dasar RemoveHandler, meneruskan peristiwa yang dirutekan dan pengendali sebagai argumen. Metode ini memungkinkan akses kode ke penyimpanan penanganan aktivitas untuk peristiwa terlampir.

WPF mengimplementasikan attached events sebagai routed events karena pengidentifikator untuk RoutedEvent ditentukan oleh sistem event WPF. Selain itu, pengarahan sebuah peristiwa adalah ekstensi alami dari konsep tingkat bahasa XAML mengenai peristiwa terlampir. Strategi implementasi ini membatasi penanganan peristiwa terlampir untuk kelas turunan UIElement atau kelas turunan ContentElement, karena hanya kelas tersebut yang memiliki implementasi AddHandler.

Misalnya, kode berikut menentukan peristiwa terlampir Clean pada kelas pemilik AquariumFilter, yang bukan kelas elemen. Kode mendefinisikan peristiwa terlampir sebagai peristiwa yang dirutekan dan mengimplementasikan metode aksesor yang diperlukan.

public class AquariumFilter
{
    // Register a custom routed event using the bubble routing strategy.
    public static readonly RoutedEvent CleanEvent = EventManager.RegisterRoutedEvent(
        "Clean", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));

    // Provide an add handler accessor method for the Clean event.
    public static void AddCleanHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
    {
        if (dependencyObject is not UIElement uiElement)
            return;

        uiElement.AddHandler(CleanEvent, handler);
    }

    // Provide a remove handler accessor method for the Clean event.
    public static void RemoveCleanHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
    {
        if (dependencyObject is not UIElement uiElement)
            return;

        uiElement.RemoveHandler(CleanEvent, handler);
    }
}
Public Class AquariumFilter

    ' Register a custom routed event using the bubble routing strategy.
    Public Shared ReadOnly CleanEvent As RoutedEvent = EventManager.RegisterRoutedEvent(
        "Clean", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))

    ' Provide an add handler accessor method for the Clean event.
    Public Shared Sub AddCleanHandler(dependencyObject As DependencyObject, handler As RoutedEventHandler)
        Dim uiElement As UIElement = TryCast(dependencyObject, UIElement)

        If uiElement IsNot Nothing Then
            uiElement.[AddHandler](CleanEvent, handler)
        End If
    End Sub

    ' Provide a remove handler accessor method for the Clean event.
    Public Shared Sub RemoveCleanHandler(dependencyObject As DependencyObject, handler As RoutedEventHandler)
        Dim uiElement As UIElement = TryCast(dependencyObject, UIElement)

        If uiElement IsNot Nothing Then
            uiElement.[RemoveHandler](CleanEvent, handler)
        End If
    End Sub

End Class

Metode RegisterRoutedEvent yang mengembalikan pengidentifikasi event terlampir adalah metode yang sama yang digunakan untuk mendaftarkan event yang dirute tetapi tidak terikat. Peristiwa rute yang terpasang dan tidak terpasang didaftarkan ke penyimpanan internal terpusat. Implementasi penyimpanan peristiwa ini memungkinkan konsep "peristiwa sebagai antarmuka" yang dibahas dalam gambaran umum peristiwa yang dirutekan .

Tidak seperti "pembungkus" peristiwa CLR yang digunakan untuk mendukung peristiwa rute yang tidak terlampir, metode akses peristiwa yang terpasang dapat diimplementasikan di kelas yang tidak diturunkan dari UIElement atau ContentElement. Ini dimungkinkan karena kode dukungan peristiwa terlampir memanggil metode UIElement.AddHandler dan UIElement.RemoveHandler pada instans UIElement yang diteruskan. Sebaliknya, pembungkus CLR untuk peristiwa rute yang tidak terpasang memanggil metode tersebut langsung pada kelas pemilik, sehingga kelas harus berasal dari UIElement.

Menaikkan peristiwa terlampir WPF

Proses untuk memicu event terpasang pada dasarnya sama dengan event tidak terpasang.

Biasanya, kode Anda tidak perlu memicu peristiwa terlampir yang sudah ada dan ditentukan oleh WPF karena peristiwa tersebut mengikuti model konseptual "layanan" secara umum. Dalam model tersebut, kelas layanan, seperti InputManager, bertanggung jawab untuk memicu peristiwa terikat yang ditentukan WPF.

Saat mendefinisikan peristiwa terlampir kustom menggunakan model WPF yang mendasarkan peristiwa terlampir pada peristiwa yang dirutekan , gunakan metode UIElement.RaiseEvent untuk memicu peristiwa terlampir pada UIElement atau ContentElement. Saat menaikkan peristiwa yang dirutekan, baik itu dilampirkan atau tidak, Anda diharuskan untuk menunjuk elemen di pohon elemen Anda sebagai sumber peristiwa. Sumber tersebut kemudian dilaporkan sebagai penelepon RaiseEvent. Misalnya, untuk menaikkan peristiwa rute terlampir AquariumFilter.Clean pada aquarium1:

aquarium1.RaiseEvent(new RoutedEventArgs(AquariumFilter.CleanEvent));
aquarium1.[RaiseEvent](New RoutedEventArgs(AquariumFilter.CleanEvent))

Dalam contoh sebelumnya, aquarium1 adalah sumber peristiwa.

Lihat juga