Bagikan melalui


Gambaran umum peristiwa terlampir (WPF .NET)

Extensible Application Markup Language (XAML) mendefinisikan komponen bahasa dan jenis peristiwa yang disebut peristiwa terlampir. Peristiwa terlampir dapat digunakan untuk menentukan peristiwa rute baru 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 peristiwa terlampir didaftarkan sebagai peristiwa yang dirutekan, ketika dinaikkan pada elemen yang mereka sebarkan melalui pohon elemen.

Penting

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

Prasyarat

Artikel ini mengasumsikan pengetahuan dasar tentang peristiwa yang dirutekan Windows Presentation Foundation (WPF), dan bahwa Anda telah membaca ringkasan 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 peristiwa dan jenis pemiliknya, dalam bentuk <owner type>.<event name>. Karena nama peristiwa memenuhi syarat dengan nama jenis pemiliknya, sintaks memungkinkan peristiwa dilampirkan ke elemen apa pun 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 AquariumFilter_Clean handler untuk AquariumFilter.Clean peristiwa terlampir ke aquarium1 elemen:

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

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

Anda juga dapat melampirkan handler untuk peristiwa terlampir dalam kode di belakang. Untuk melakukannya, panggil AddHandler metode pada objek yang harus dilampirkan oleh handler dan teruskan pengidentifikasi peristiwa dan handler sebagai parameter ke metode .

Cara WPF mengimplementasikan peristiwa terlampir

Peristiwa terlampir WPF diimplementasikan sebagai peristiwa yang dirutekan yang didukung oleh RoutedEvent bidang. 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, peristiwa terlampir digunakan di area fitur tertentu di mana ada abstraksi tingkat layanan. Misalnya, WPF menggunakan peristiwa terlampir yang diaktifkan oleh statis Mouse atau Validation kelas. 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 terlampir Mouse.MouseDown yang mendasar pada UIElement melalui peristiwa yang dirutekan yang setara UIElement.MouseDown 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 menaikkan Mouse.MouseDown untuk mensimulasikan input mouse, dan tidak perlu berasal dari Mouse untuk melakukannya. Skenario itu melibatkan penanganan kode peristiwa, karena penanganan XAML dari peristiwa yang terlampir tidak akan relevan.

Menangani peristiwa 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 secara 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 dinaikkan dalam kode dan bergantung pada penanganan kelas di kelas induk yang relevan. Misalnya, item dalam diharapkan Selector untuk menaikkan Selected peristiwa terlampir, yang kemudian ditangani oleh Selector kelas. Kelas Selector berpotensi mengonversi Selected peristiwa menjadi peristiwa yang dirutekan SelectionChanged . Untuk informasi selengkapnya tentang peristiwa yang dirutekan dan penanganan kelas, lihat Menandai peristiwa yang dirutekan sebagai 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:

  • Metode Tambahkan<nama>peristiwa Handler , dengan parameter pertama yang merupakan elemen tempat penanganan aktivitas dilampirkan, dan parameter kedua yang menjadi penanganan aktivitas untuk ditambahkan. Metode harus public dan static, tanpa nilai pengembalian. Metode ini memanggil AddHandler metode kelas dasar, meneruskan peristiwa yang dirutekan dan handler 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.

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

WPF menerapkan peristiwa terlampir sebagai peristiwa yang dirutekan karena pengidentifikasi untuk RoutedEvent didefinisikan oleh sistem peristiwa WPF. Selain itu, perutean peristiwa adalah ekstensi alami dari konsep tingkat bahasa XAML dari peristiwa terlampir. Strategi implementasi ini membatasi penanganan peristiwa terlampir untuk UIElement kelas turunan atau ContentElement kelas turunan, karena hanya kelas tersebut yang memiliki AddHandler implementasi.

Misalnya, kode berikut menentukan Clean peristiwa terlampir pada AquariumFilter kelas pemilik, 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 peristiwa terlampir adalah metode yang sama yang digunakan untuk mendaftarkan peristiwa rute yang tidak terpasang. 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 mengembalikan peristiwa yang dirutekan yang tidak terpasang, metode aksesor peristiwa yang terpasang dapat diimplementasikan di kelas yang tidak berasal dari UIElement atau ContentElement. Ini dimungkinkan karena kode dukungan peristiwa terlampir memanggil UIElement.AddHandler metode dan UIElement.RemoveHandler pada instans yang diteruskan UIElement . 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 menaikkan peristiwa terlampir pada dasarnya sama dengan peristiwa yang tidak terpasang.

Biasanya, kode Anda tidak perlu menaikkan peristiwa terlampir yang ditentukan WPF yang ada karena peristiwa tersebut mengikuti model konseptual "layanan" umum. Dalam model itu, kelas layanan, seperti InputManager, bertanggung jawab untuk menaikkan peristiwa terlampir yang ditentukan WPF.

Saat menentukan peristiwa terlampir kustom menggunakan model WPF peristiwa terlampir basing pada peristiwa yang dirutekan, gunakan UIElement.RaiseEvent metode untuk menaikkan peristiwa terlampir pada setiap 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 pemanggil RaiseEvent . Misalnya, untuk menaikkan AquariumFilter.Clean peristiwa yang dirutekan yang dilampirkan pada aquarium1:

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

Dalam contoh sebelumnya, aquarium1 adalah sumber peristiwa.

Baca juga