Gönderilmiş Olayları İşlenmiş Olarak İşaretleme ve Sınıf İşlemesi

Yönlendirilmiş bir olayın işleyicileri, olay verileri içinde işlenen olayı işaretleyebilir. Olayın işlenmesi, yolu etkili bir şekilde kısaltır. Sınıf işleme, yönlendirilen olaylar tarafından desteklenen bir programlama kavramıdır. Sınıf işleyicisi, sınıfın herhangi bir örneğindeki herhangi bir örnek işleyiciden önce çağrılan bir işleyici ile sınıf düzeyinde belirli bir yönlendirilmiş olayı işleme fırsatına sahiptir.

Ön koşullar

Bu konu başlığında, Yönlendirilen Olaylara Genel Bakış'ta tanıtılan kavramlar açıklanmaktadır.

Olayları İşlenmiş Olarak İşaretlenme Zamanları

Yönlendirilen bir olayın olay verilerinde özelliğinin Handledtrue değerini olarak ayarladığınızda, buna "işlenen olayı işaretleme" denir. Yönlendirilmiş olayları işlenmiş olarak işaretlemeniz gerektiğinde, uygulama yazarı olarak veya mevcut yönlendirilmiş olaylara yanıt veren veya yeni yönlendirilen olayları uygulayan bir denetim yazarı olarak işaretlemeniz gereken mutlak bir kural yoktur. Çoğunlukla, yönlendirilen olayın olay verilerinde taşınan "işlenen" kavramı, kendi uygulamanızın WPF API'lerinde kullanıma sunulan çeşitli yönlendirilmiş olaylara ve özel yönlendirilen olaylara verdiği yanıtlar için sınırlı bir protokol olarak kullanılmalıdır. "İşlenen" sorunu göz önünde bulundurmanın bir diğer yolu da, kodunuz yönlendirilen olaya önemli ve nispeten eksiksiz bir şekilde yanıt verdiyse yönlendirilmiş bir olayı genel olarak işaretlemelisiniz. Genellikle, tek bir yönlendirilmiş olay oluşumu için ayrı işleyici uygulamaları gerektiren birden fazla önemli yanıt olmamalıdır. Daha fazla yanıt gerekiyorsa, yönlendirme için yönlendirilmiş olay sistemini kullanmak yerine tek bir işleyici içinde zincirlenmiş uygulama mantığı aracılığıyla gerekli kodun uygulanması gerekir. "Önemli" kavramı da özneldir ve uygulamanıza veya kodunuza bağlıdır. Genel rehberlik olarak, bazı "önemli yanıt" örnekleri şunlardır: odağı ayarlama, genel durumu değiştirme, görsel gösterimi etkileyen özellikleri ayarlama ve diğer yeni olayları oluşturma. Önemsiz yanıtlara örnek olarak şunlar verilebilir: özel durumu değiştirme (görsel etki olmadan veya programlı gösterim), olayların günlüğe kaydedilmesi veya bir olayın bağımsız değişkenlerine bakıp yanıt vermemeye seçme.

XAML'de eklenen işleyiciler veya ortak imzası AddHandler , olay verilerinin zaten işlenmiş olarak işaretlendiği yönlendirilmiş bir olaya yanıt olarak çağrılmadığı için, yönlendirilen olay sistemi davranışı bu "önemli yanıt" modelini yönlendirilmiş bir olayın işlenmiş durumunu kullanmak için güçlendirir. Olay yolundaki önceki katılımcılar tarafından işlenen yönlendirilmiş olayları işlemek için parametre sürümüne (AddHandler(RoutedEvent, Delegate, Boolean)) sahip handledEventsToo bir işleyici eklemeye yönelik ek çabayı göstermelisiniz.

Bazı durumlarda denetimler, belirli yönlendirilmiş olayları işlenmiş olarak işaretler. İşlenen yönlendirilmiş olay, WPF denetim yazarlarının denetimin yönlendirilen olaya yanıt olarak gerçekleştirilen eylemlerinin denetim uygulamasının bir parçası olarak önemli veya eksiksiz olduğuna ve olayın daha fazla işlenmesi gerekmeyen bir kararı temsil eder. Bu genellikle bir olay için sınıf işleyicisi eklenerek veya temel sınıfta var olan sınıf işleyicisi sanallarından biri geçersiz kılınarak yapılır. Gerekirse bu olay işlemeye geçici bir çözüm bulabilirsiniz; Bu konunun devamında Yer alan Denetimler Tarafından Olay Engellemeye Geçici Çözüm Bulma konusuna bakın.

"Önizleme" (Tünel Oluşturma) Olayları ile Kabarcık Olayları ve Olay İşleme karşılaştırması

Yönlendirilen olayların önizlemesi, öğe ağacı üzerinden tünel oluşturma yolunu izleyen olaylardır. Adlandırma kuralında ifade edilen "Önizleme", önizleme (tünel oluşturma) yönlendirilen olayların eşdeğer kabarcıklı yönlendirilmiş olaydan önce tetiklendiği giriş olayları için genel ilkeyi belirtir. Ayrıca, tünel ve kabarcık çifti olan giriş yönlendirilmiş olayların ayrı bir işleme mantığı vardır. Tünel oluşturma/önizleme yönlendirilen olay bir olay dinleyicisi tarafından işlendi olarak işaretlenirse, kabarcıklı yönlendirilen olay, kabarcık oluşturan yönlendirilen olayın dinleyicileri almadan önce bile işlendi olarak işaretlenir. Tünel oluşturma ve köpeğe yönlendirilen olaylar teknik olarak ayrı olaylardır, ancak bu davranışı etkinleştirmek için olay verilerinin aynı örneğini kasıtlı olarak paylaşırlar.

Tünel oluşturma ve kabarcıklama yönlendirilen olaylar arasındaki bağlantı, herhangi bir WPF sınıfının kendi bildirilen yönlendirilmiş olaylarını nasıl oluşturduğunun iç uygulamasıyla gerçekleştirilir ve bu eşleştirilmiş giriş yönlendirilen olaylar için geçerlidir. Ancak bu sınıf düzeyi uygulama mevcut değilse, tünel yönlendirmeli olay ile adlandırma düzenini paylaşan kabarcıklı yönlendirilmiş olay arasında bağlantı yoktur: böyle bir uygulama olmadan tamamen ayrı yönlendirilmiş iki olay olur ve sıralı olarak tetiklenmez veya olay verilerini paylaşmaz.

Özel bir sınıfta tünel/kabarcık girişi yönlendirilmiş olay çiftlerini uygulama hakkında daha fazla bilgi için bkz . Özel Yönlendirilmiş Olay Oluşturma.

Sınıf İşleyicileri ve Örnek İşleyicileri

Yönlendirilen olaylar, olay için iki farklı dinleyici türünü dikkate alır: sınıf dinleyicileri ve örnek dinleyicileri. Sınıf dinleyicileri, türlerin statik oluşturucusunda belirli EventManager bir API'yiRegisterClassHandler çağırması veya bir öğe temel sınıfından sınıf işleyicisi sanal yöntemini geçersiz kılması nedeniyle vardır. Örnek dinleyicileri, bir veya daha fazla işleyicinin yönlendirilen olay için çağrısıyla AddHandlereklendiği belirli sınıf örnekleri/öğeleridir. Mevcut WPF yönlendirilmiş olayları, ortak dil çalışma zamanı (CLR) olay sarmalayıcısının bir parçası olarak çağrısı AddHandler yapar ve olay uygulamalarını ekler{} ve kaldırır{} . Bu, aynı zamanda bir öznitelik söz dizimi aracılığıyla olay işleyicilerini eklemeye yönelik basit XAML mekanizmasının da etkinleştirilme şeklidir. Bu nedenle, basit XAML kullanımı bile bir çağrıya AddHandler eşit olur.

Görsel ağaç içindeki öğeler kayıtlı işleyici uygulamaları için denetleniyor. İşleyiciler yol boyunca, yönlendirilen olay için yönlendirme stratejisinin türüne göre sırasıyla çağrılabilir. Örneğin, köpeğe yönlendirilen olaylar önce yönlendirilen olayı tetikleyen aynı öğeye eklenmiş olan işleyicileri çağırır. Ardından yönlendirilen olay bir sonraki üst öğeye "kabarcıklar" ve uygulama kök öğesine ulaşılana kadar böyle devam eder.

Bir kabarcıklama yolundaki kök öğenin perspektifinden bakıldığında, sınıf işlemesi veya yönlendirilen olayın kaynağına yakın herhangi bir öğe, olay bağımsız değişkenlerini işleniyor olarak işaretleyen işleyicileri çağırırsa, kök öğelerdeki işleyiciler çağrılmaz ve olay yolu bu kök öğeye ulaşmadan önce etkili bir şekilde kısaltılır. Ancak, bir sınıf işleyicisi veya örnek işleyicisi yönlendirilen olayı işlendi olarak işaretlese bile, işleyiciler çağrılmaları gereken özel bir koşullu kullanılarak eklenebildiği için yol tamamen durdurulmuyor. Bu, bu konunun devamında Olaylar İşlendiğinde Bile Tetiklenen Örnek İşleyicileri Ekleme bölümünde açıklanmıştır.

Olay yolundan daha derin bir düzeyde, bir sınıfın herhangi bir örneğine göre hareket eden birden çok sınıf işleyicisi de olabilir. Bunun nedeni, yönlendirilen olaylar için sınıf işleme modelinin bir sınıf hiyerarşisindeki tüm olası sınıfların her biri yönlendirilen her olay için kendi sınıf işleyicisini kaydetmesini sağlar. Her sınıf işleyicisi bir iç depoya eklenir ve bir uygulamanın olay yolu oluşturulduğunda, sınıf işleyicilerinin tümü olay yoluna eklenir. Sınıf işleyicileri, en çok türetilen sınıf işleyicisi önce çağrılacak şekilde yola eklenir ve her ardışık temel sınıftan sınıf işleyicileri çağrılır. Genel olarak, sınıf işleyicileri zaten işlenmiş olarak işaretlenmiş yönlendirilmiş olaylara da yanıt verecek şekilde kaydedilmez. Bu nedenle, bu sınıf işleme mekanizması iki seçeneknden birini etkinleştirir:

  • Türetilmiş sınıflar, temel sınıf işleyicisi türetilen sınıf işleyicisinden bir süre sonra çağrılacağından, işlenen yönlendirilmiş olayı işaretlemeyen bir işleyici ekleyerek temel sınıftan devralınan sınıf işlemeye destek olabilir.

  • Türetilmiş sınıflar, işlenen yönlendirilmiş olayı işaretleyen bir sınıf işleyicisi ekleyerek temel sınıftan sınıf işlemesinin yerini alabilir. Görsel görünüm, durum mantığı, giriş işleme ve komut işleme gibi alanlarda hedeflenen temel denetim tasarımını değiştirebileceğinden bu yaklaşımda dikkatli olmanız gerekir.

Denetim Temeli Sınıflarına Göre Yönlendirilmiş Olayların Sınıf İşlemesi

Bir olay yolundaki belirli bir öğe düğümünde, sınıf dinleyicileri, öğedeki herhangi bir örnek dinleyicisi tarafından yönlendirilmeden önce yönlendirilen olaya yanıt verme fırsatına sahiptir. Bu nedenle, sınıf işleyicileri bazen belirli bir denetim sınıfı uygulamasının daha fazla yaymak istemediğiniz yönlendirilmiş olayları bastırmak veya sınıfın bir özelliği olan bu yönlendirilmiş olayın özel işlenmesini sağlamak için kullanılır. Örneğin, bir sınıf, belirli bir sınıf bağlamında bazı kullanıcı giriş koşulunun ne anlama geldiğini daha ayrıntılı bir şekilde içeren kendi sınıfa özgü olayını tetikler. Sınıf uygulaması daha sonra daha genel yönlendirilmiş olayı işlenmiş olarak işaretleyebilir. Sınıf işleyicileri genellikle paylaşılan olay verilerinin zaten işlenmiş olarak işaretlendiği yönlendirilmiş olaylar için çağrılmayacak şekilde eklenir, ancak atipik durumlar için, yönlendirilen olaylar işlendiğinde bile çağrılmak üzere sınıf işleyicilerini kaydeden bir RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) imza da vardır.

Sınıf İşleyici Sanalları

Bazı öğeler, özellikle gibi UIElementtemel öğeler, genel yönlendirilmiş olaylar listesine karşılık gelen boş "On*Event" ve "OnPreview*Event" sanal yöntemlerini kullanıma sunar. Bu sanal yöntemler, yönlendirilen olay için bir sınıf işleyicisi uygulamak üzere geçersiz kılınabilir. Temel öğe sınıfları, daha önce açıklandığı gibi kullanarak RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) bu sanal yöntemleri bu tür yönlendirilmiş her olay için sınıf işleyicisi olarak kaydeder. On*Event sanal yöntemleri, her tür için statik oluşturucularda özel başlatma gerektirmeden ilgili yönlendirilmiş olaylar için sınıf işlemeyi uygulamayı çok daha basit hale getirir. Örneğin, sanal yöntemi geçersiz kılarak OnDragEnter türetilmiş herhangi bir UIElement sınıfta olay için DragEnter sınıf işleme ekleyebilirsiniz. Geçersiz kılma içinde, yönlendirilen olayı işleyebilir, diğer olayları tetikleyebilir, örneklerdeki öğe özelliklerini değiştirebilecek sınıfa özgü mantık başlatabilir veya bu eylemlerin herhangi bir bileşimini başlatabilirsiniz. İşlenen olayı işaretleseniz bile bu tür geçersiz kılmalarda genellikle temel uygulamayı çağırmanız gerekir. Sanal yöntem temel sınıfta olduğundan temel uygulamanın çağrılması kesinlikle önerilir. Her sanaldan temel uygulamaları çağırmanın standart korumalı sanal deseni temelde yönlendirilmiş olay sınıfı işlemeye yerel olan benzer bir mekanizmanın yerini alır ve paralel hale gelir; burada sınıf hiyerarşisindeki tüm sınıflar için sınıf işleyicileri, en çok türetilmiş sınıfın işleyicisinden başlayıp temel sınıf işleyicisine devam ederek belirli bir örnekte çağrılır. Yalnızca sınıfınızın temel sınıf işleme mantığını değiştirmek için kasıtlı bir gereksinimi varsa temel uygulama çağrısını atlamalısınız. Temel uygulamayı geçersiz kılma kodunuzdan önce veya sonra çağırmak, uygulamanızın doğasına bağlıdır.

Giriş Olay Sınıfı İşleme

Sınıf işleyicisi sanal yöntemlerinin tümü, yalnızca paylaşılan olay verilerinin işlendi olarak işaretlenmediği durumlarda çağrılacak şekilde kaydedilir. Ayrıca, benzersiz giriş olayları için tünel oluşturma ve kabarcıklama sürümleri genellikle sıralı olarak oluşturulur ve olay verilerini paylaşır. Bu, giriş olaylarının belirli bir sınıf işleyici çifti için birinin tünel oluşturma sürümü, diğerinin de kabarcıklı sürüm olduğu durumlarda, işlenen olayı hemen işaretlemek istemeyebileceğinizi gerektirir. İşlenen olayı işaretlemek için tünel sınıfı işleme sanal yöntemini uygularsanız, bu, kabarcık oluşturan sınıf işleyicisinin çağrılmasını engeller (ayrıca tünel oluşturma veya kabarcıklama olayı için normal olarak kaydedilmiş örnek işleyicilerinin çağrılmasını engeller).

Bir düğümdeki sınıf işleme tamamlandıktan sonra örnek dinleyicileri dikkate alınır.

Olaylar İşlendi olarak işaretlendiğinde bile tetiklenen örnek işleyicileri ekleme

yöntemi, AddHandler bir olay yoldaki işleme öğesine ulaştığında olay sistemi tarafından çağrılacak işleyiciler eklemenize olanak tanıyan belirli bir aşırı yükleme sağlar. Başka bir işleyici olay verilerini bu olayı işlenmiş olarak işaretleyecek şekilde ayarlamış olsa bile. Bu genellikle yapılmaz. Genellikle işleyiciler, birden çok uç sonucu istense bile bir öğe ağacında nerede işlendiğine bakılmaksızın bir olaydan etkilenecek uygulama kodunun tüm alanlarını ayarlamak için yazılabilir. Ayrıca, genellikle bu olaya yanıt vermesi gereken yalnızca bir öğe vardır ve uygun uygulama mantığı zaten gerçekleşmiştir. handledEventsToo Ancak aşırı yükleme, bir öğe ağacındaki veya denetim bileşimindeki diğer bazı öğelerin zaten bir olayı işlendi olarak işaretlediği, ancak öğe ağacındaki diğer öğelerin (rotaya bağlı olarak) kendi işleyicilerinin çağrılmaya devam etmek istediği olağanüstü durumlar için kullanılabilir.

İşlenen Olaylar İşlenmemiş Olarak ne zaman işaretlenir?

Genel olarak, işlenen olarak işaretlenen yönlendirilmiş olaylar üzerinde işlem handledEventsTooyürüten işleyiciler tarafından bile işlenmemiş olarak işaretlenmemelidir (Handled yeniden falseolarak ayarlanmalıdır). Ancak, bazı giriş olayları, ağaçta bir konumda üst düzey olay ve başka bir konumda alt düzey olay görüldüğünde çakışabilen üst düzey ve alt düzey olay gösterimlerine sahiptir. Örneğin, bir alt öğenin gibi bir üst öğe gibi KeyDowndüşük düzeyli bir olayı dinlerken olduğu gibi TextInput üst düzey bir anahtar olayını dinlediği durumu düşünün. Üst öğe düşük düzey olayı işlerse, üst düzey olay, sezgisel olarak ilk olay işleme fırsatına sahip olması gereken alt öğede bile gizlenebilir.

Bu gibi durumlarda, alt düzey olay için hem üst öğelere hem de alt öğelere işleyici eklemek gerekebilir. Alt öğe işleyicisi uygulaması alt düzey olayı işlendi olarak işaretleyebilir, ancak üst öğe işleyicisi uygulaması, ağaçtan sonraki öğelerin (ve üst düzey olayın) yanıt verme fırsatına sahip olabilmesi için yeniden işlenmemiş olarak ayarlar. Bu durum oldukça nadir olmalıdır.

Denetim Oluşturma için Giriş Olaylarını Kasıtlı Olarak Gizleme

Yönlendirilen olayların sınıf işlemesinin kullanıldığı ana senaryo, giriş olayları ve bileşik denetimler içindir. Bileşik denetim, birden çok pratik denetimden veya denetim temel sınıfından oluşan bir tanımdır. Denetimin yazarı genellikle tüm denetimi tekil olay kaynağı olarak raporlamak için her bir alt bileşenin oluşturabileceği tüm olası giriş olaylarını birbirine eklemek ister. Bazı durumlarda, denetim yazarı bileşenlerden gelen olayları tamamen gizlemeyi veya daha fazla bilgi taşıyan veya daha belirli bir davranışa işaret eden bileşen tanımlı bir olayı değiştirmek isteyebilir. Herhangi bir bileşen yazarı tarafından hemen görülebilen kurallı örnek, Windows Presentation Foundation'ın (WPF) Button sonunda tüm düğmelerin sahip olduğu sezgisel olaya çözümlenecek herhangi bir fare olayını nasıl işlediğidir: olay Click .

Button Temel sınıf (ButtonBase), ve 'den UIElementControlFrameworkElement türetilen temel sınıf ve denetim girişi işleme için gereken olay altyapısının büyük bir kısmı düzeyinde kullanılabilir.UIElement Özellikle, UIElement sınırları içinde fare imleci için isabet testini işleyen genel Mouse olayları işler ve gibi MouseLeftButtonDownen yaygın düğme eylemleri için ayrı olaylar sağlar. UIElementayrıca için MouseLeftButtonDownönceden kaydedilen sınıf işleyicisi olarak boş bir sanal OnMouseLeftButtonDown sağlar ve ButtonBase geçersiz kılar. Benzer şekilde, ButtonBase için MouseLeftButtonUpsınıf işleyicilerini kullanır. Olay verilerine geçirilen geçersiz kılmalarda, uygulamalar bu RoutedEventArgs örneği olarak ayarlanarak Handledtrueişleniyor olarak işaretler ve aynı olay verileri, yolun geri kalanında diğer sınıf işleyicilerine ve örnek işleyicilerine veya olay ayarlayıcılarına devam eder. Ayrıca, OnMouseLeftButtonUp geçersiz kılma daha sonra olayı tetikler Click . Çoğu dinleyici için sonuç, ve MouseLeftButtonUp olaylarının "kaybolması" ve yerine Clickile değiştirilmesidirMouseLeftButtonDown. Bu olayın, düğmenin bileşik bir parçasından değil de gerçek bir düğmeden veya başka bir öğeden tamamen kaynaklandığı bilindiğinden daha fazla anlam taşıyan bir olaydır.

Denetimler Tarafından Olay Gizlemeyi Geçici Olarak Çözme

Bazen tek tek denetimler içindeki bu olay gizleme davranışı, uygulamanız için olay işleme mantığının bazı genel amaçlarına müdahale edebilir. Örneğin, herhangi bir nedenle uygulamanızın uygulama kök öğesinde bulunan bir işleyicisi MouseLeftButtonDown varsa, bir düğmeye fare tıklamasının kök düzeyinde çağrılmadığını MouseLeftButtonDown veya MouseLeftButtonUp işleyiciler olmadığını fark edebilirsiniz. Olayın kendisi aslında kabardı (yine, olay yolları gerçekten sona ermez, ancak yönlendirilen olay sistemi işlendi olarak işaretlendikten sonra işleyici çağırma davranışını değiştirir). Yönlendirilen olay düğmeye ulaştığında, ButtonBase sınıf işlemesi olayı daha fazla anlamla değiştirmek istediği için işleneni Click işaretlediMouseLeftButtonDown. Bu nedenle, yolu daha ileriye doğru herhangi bir standart MouseLeftButtonDown işleyici çağrılmayacak. İşleyicilerinizin bu durumda çağrılmasını sağlamak için kullanabileceğiniz iki teknik vardır.

İlk teknik, imzasını kullanarak işleyiciyi handledEventsToo kasıtlı olarak eklemektir AddHandler(RoutedEvent, Delegate, Boolean). Bu yaklaşımın bir sınırlaması, olay işleyicisi eklemeye yönelik bu tekniğin işaretlemeden değil yalnızca koddan mümkün olmasıdır. Olay işleyicisi adını Genişletilebilir Uygulama İşaretleme Dili (XAML) aracılığıyla olay özniteliği değeri olarak belirtmenin basit söz dizimi bu davranışı etkinleştirmez.

İkinci teknik yalnızca yönlendirilen olayın tünel oluşturma ve kabarcıklama sürümlerinin eşleştirildiği giriş olayları için çalışır. Bu yönlendirilmiş olaylar için, bunun yerine önizleme/tünel eşdeğeri yönlendirilmiş olaya işleyiciler ekleyebilirsiniz. Bu yönlendirilen olay, kökten başlayarak yol boyunca tünel oluşturur, bu nedenle düğme sınıfı işleme kodu uygulamanın öğe ağacındaki bir üst öğe düzeyinde Önizleme işleyicisini eklediğiniz varsayılır. Bu yaklaşımı kullanıyorsanız işlenen önizleme olaylarını işaretleme konusunda dikkatli olun. Kök öğesinde işlenmekte olan PreviewMouseLeftButtonDown örnek için, olayı işleyici uygulamasında olarak Handled işaretlediyseniz, olayı gerçekten gizlemeniz Click gerekir. Bu genellikle arzu edilen bir davranış değildir.

Ayrıca bkz.