Aracılığıyla paylaş


Ekli olaylara genel bakış (WPF .NET)

Genişletilebilir Uygulama Biçimlendirme Dili (XAML),ekli olay adı verilen bir dil bileşenini ve olay türünü tanımlar. Ekli olaylar, öğe olmayan bir sınıfta yeni bir yönlendirilmiş olay tanımlamak ve bu olayı ağacınızdaki herhangi bir öğeye yükseltmek için kullanılabilir. Bunu yapmak için, ekli olayı yönlendirilmiş olay olarak kaydetmeniz ve ekli olay işlevselliğini destekleyen belirli yedekleme kodu sağlamanız gerekir. Ekli olaylar yönlendirilmiş olaylar olarak kaydedildiğinden, bir öğeye yükseltildiğinde öğe ağacına yayılırlar.

Önkoşullar

Makalede, Windows Presentation Foundation (WPF) tarafından yönlendirilen olaylar hakkında temel bilgiler edindiğiniz ve WPF ve XAML'Yönlendirilen olaylara genel bakış makalesini okuduğunuz varsayılır. Bu makaledeki örnekleri takip etmek için XAML hakkında bilgi sahibi olmanız ve WPF uygulamalarının nasıl yazabileceğinizi bilmeniz yardımcı olur.

Ekli olay söz dizimi

XAML söz diziminde, ekli bir olay, olay adı ve sahip türü, <owner type>.<event name>biçiminde belirtilir. Olay adı, sahip türünün adıyla nitelendiğinden, söz dizimi olayın örneklenebilen herhangi bir öğeye eklenmesini sağlar. Bu söz dizimi, olay yolu boyunca rastgele bir öğeye iliştirilen normal yönlendirilmiş olaylar için işleyiciler için de geçerlidir.

Aşağıdaki XAML özniteliği söz dizimi, ekli AquariumFilter.Clean olayının AquariumFilter_Clean işleyicisini aquarium1 öğesine ekler:

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

Bu örnekte, AquariumFilter ve Aquarium sınıfları farklı bir ortak dil çalışma zamanı (CLR) ad alanı ve derlemesinde bulunduğundan aqua: ön eki gereklidir.

Ayrıca arkaplan kodunda iliştirilmiş olaylar için işleyiciler ekleyebilirsiniz. Bunu yapmak için, işleyicinin eklemesi gereken nesnede AddHandler yöntemini çağırın ve olay tanımlayıcısını ve işleyicisini yönteme parametre olarak geçirin.

WPF ekli olayları nasıl uygular?

WPF ekli olayları, RoutedEvent alanı tarafından desteklenen yönlendirilmiş olaylar olarak gerçekleştirilir. Sonuç olarak, ekli olaylar yükseltildikten sonra öğe ağacı boyunca yayılır. Genellikle, olay kaynağı olarak bilinen ekli olayı yükselten nesne bir sistem veya hizmet kaynağıdır. Sistem veya hizmet kaynakları, öğe ağacının doğrudan bir parçası değildir. Diğer ekli olaylar için olay kaynağı, bileşik denetim içindeki bir bileşen gibi ağaçtaki bir öğe olabilir.

Ekli olay senaryoları

WPF'de ekli olaylar, hizmet düzeyi soyutlamanın bulunduğu belirli özellik alanlarında kullanılır. Örneğin WPF, statik Mouse veya Validation sınıfları tarafından etkinleştirilen ekli olayların kullanımlarını yapar. Bir hizmetle etkileşim kuran veya hizmet kullanan sınıflar, ekli olay söz dizimini kullanarak bir olayla etkileşimde bulunabilir veya ekli olayı yönlendirilmiş olay olarak ortaya çıkarabilirsiniz. İkinci seçenek, bir sınıfın hizmetin özelliklerini nasıl tümleştirebileceğinin bir parçasıdır.

WPF giriş sistemi, ekli olayları kapsamlı olarak kullanır. Ancak, bu bağlı olayların neredeyse tümü, temel öğeler aracılığıyla ekli olmayan eşdeğer yönlendirilmiş olaylar olarak görünür. Yönlendirilen her giriş olayı, temel öğe sınıfının bir üyesidir ve bir CLR olay "sarmalayıcı fonksiyon" ile desteklenmiştir. Ekli olayları nadiren doğrudan kullanır veya işlersiniz. Örneğin, bir UIElement üzerinde temel ekli Mouse.MouseDown olayını eşdeğer UIElement.MouseDown yönlendirilmiş olay aracılığıyla işlemek, XAML'de veya arka plan kodda ekli olay söz dizimini kullanmaktan daha kolaydır.

Ekli olaylar, giriş cihazlarının gelecekte genişletilmesini sağlayarak bir mimari amacına hizmet eder. Örneğin, yeni bir giriş cihazının, fare girişi simülasyonu yapmak için yalnızca Mouse.MouseDown'ı yükseltmesi gerekir ve bunu yapmak için Mouse'den türetilmesine gerek yoktur. Bu senaryo, ekli olayın XAML ile işlenmesinin ilgili olmayacağından, olayın kodla işlenmesini içerir.

Ekli olayı işleme

Ekli olayı kodlama ve işleme işlemi temel olarak ekli olmayan yönlendirilmiş bir olayla aynıdır.

Daha öncebelirtildiği gibi, mevcut WPF ekli olayları genellikle WPF'de doğrudan işlenmek üzere tasarlanmamıştır. Daha sık olarak, ekli bir olayın amacı bileşik denetim içindeki bir öğenin durumunu denetim içindeki bir üst öğeye raporlamasını sağlamaktır. Bu senaryoda, olay kodda oluşturulur ve ilgili üst sınıfta sınıf işlemeye dayanır. Örneğin, bir Selector içindeki öğelerin ekli Selected olayını oluşturması beklenir ve bu olay daha sonra Selector sınıfı tarafından sınıf düzeyinde işlenir. Selector sınıfı, Selected olayını potansiyel olarak SelectionChanged yönlendirilmiş olaya dönüştürür. Yönlendirilen olaylar ve sınıf işleme hakkında daha fazla bilgi için Yönlendirilen olayların işlenmiş olarak işaretlenmesi vesınıf işleme belgelerine bakın.

Özel bir ekli olay tanımlama

Ortak WPF temel sınıflarından türetiyorsanız, özel ekli olayınızı sınıfınıza iki erişimci yöntemi ekleyerek uygulayabilirsiniz. Bu yöntemler şunlardır:

  • Bir Ekle<etkinlik adı>işleyicisi yöntemi, ilk parametresi olay işleyicisinin eklendiği eleman olan ve ikinci parametresi eklenmesi gereken olay işleyicisi olan bir metot. Yöntem, dönüş değeri olmadan public ve staticolmalıdır. Yöntem, yönlendirilen olayı ve işleyiciyi bağımsız değişken olarak geçirerek AddHandler'ın temel sınıf yöntemini çağırır. Bu yöntem, bir öğeye olay işleyicisi eklemek için XAML özniteliği söz dizimini destekler. Bu yöntem ayrıca ekli olay için olay işleyici deposuna kod erişimi sağlar.

  • olay işleyicisinin eklendiği öğe olan ilk parametreye ve kaldırılacak olay işleyicisi olan ikinci parametreye sahip>handler yöntemi<olay adını kaldırın. Yöntem, dönüş değeri olmadan public ve staticolmalıdır. Yöntem, yönlendirilen olayı ve işleyiciyi argüman olarak geçirerek RemoveHandler taban sınıf yöntemini çağırır. Bu yöntem, ekli olay için olay işleyici deposuna kod erişimini etkinleştirir.

RoutedEvent tanımlayıcısı WPF olay sistemi tarafından tanımlandığından, WPF, ekli olayları yönlendirilmiş olaylar olarak uygular. Ayrıca, bir olayı yönlendirme, ekli bir olayın XAML dil düzeyi kavramının doğal bir uzantısıdır. Bu uygulama stratejisi, yalnızca bu sınıfların AddHandler uygulamaları olduğu için ekli olayların işlenmesini ya türetilmiş UIElement sınıflarıyla ya da türetilmiş ContentElement sınıflarıyla kısıtlar.

Örneğin, aşağıdaki kod bir öğe sınıfı olmayan AquariumFilter sahip sınıfında ekli Clean olayını tanımlar. Kod, ekli olayı yönlendirilmiş bir olay olarak tanımlar ve gerekli erişimci yöntemlerini uygular.

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

Ekli olay tanımlayıcısını döndüren RegisterRoutedEvent yöntemi, eklenmemiş yönlendirilmiş olayları kaydetmek için kullanılan yöntemle aynıdır. Hem ekli hem de bağlı olmayan yönlendirilmiş olaylar merkezi bir iç depoya kaydedilir. Bu olay deposu uygulaması, "Olaylar bir arabirim olarak" kavramının tartışıldığıYönlendirilmiş olaylara genel bakış bölümünü etkinleştirir.

Bağlı olmayan yönlendirilmiş olayları desteklemek için kullanılan CLR olayı "sarmalayıcı"sından farklı olarak, bağlı olay erişim yöntemleri UIElement veya ContentElement'den türetilmeyen sınıflarda uygulanabilir. Ekli olay yedekleme kodu, geçirilen bir UIElement örneğinde UIElement.AddHandler ve UIElement.RemoveHandler yöntemlerini çağırdığından bu mümkündür. Buna karşılık, bağlı olmayan yönlendirilmiş olaylar için CLR sarmalayıcısı bu yöntemleri doğrudan sahip olan sınıfta çağırır, böylece sınıfın UIElement'den türetilmesi gerekir.

WPF ekli olayı tetikleme

Ekli olay oluşturma işlemi temelde ekli olmayan yönlendirilmiş bir olayla aynıdır.

Normalde, bu olaylar genel "hizmet" kavramsal modelini izlediğinden kodunuzun mevcut WPF tanımlı ekli olayları oluşturması gerekmez. Bu modelde, InputManagergibi hizmet sınıfları WPF tanımlı ekli olayları oluşturmakla sorumludur.

Özel bir ekli olay tanımlarken,yönlendirilmiş olaylara dayalı WPF modelini kullanarak, herhangi bir veya üzerinde bir ekli olay oluşturmak için yöntemini kullanın. Bağlı olsun veya olmasın yönlendirilmiş bir olayı oluştururken, öğe ağacınızdaki bir öğeyi olay kaynağı olarak atamanız gerekir. Kaynak daha sonra RaiseEvent'ı arayan olarak bildirilir. Örneğin, AquariumFilter.Clean bağlı bir yönlendirilmiş olayı aquarium1üzerinde tetiklemek için:

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

Önceki örnekte olay kaynağı aquarium1.

Ayrıca bkz.