Gönderilmiş Olayları İşlenmiş Olarak İşaretleme ve Sınıf İşlemesi
Yönlendirilmiş bir olaya yönelik işleyiciler olay verileri içinde işlenen olayı işaretleyebilir. Olayı işlemek, yolu etkin bir şekilde kısaltacak. Sınıf işleme, yönlendirilmiş olaylar tarafından desteklenen bir programlama kavramıdır. Sınıf işleyicisi, sınıfın herhangi bir örneği üzerinde herhangi bir örnek işleyicisinden önce çağrılan bir işleyiciyle bir sınıf düzeyinde belirli bir yönlendirilmiş olayı işleme fırsatına sahiptir.
Önkoşullar
Bu konu, yönlendirilmiş olaylara genel bakışbölümünde tanıtılan kavramlara elaborates.
Olayları Işlenmiş olarak Işaretleme
Özelliğinin değerini, Handledtrue yönlendirilmiş bir olayın olay verilerinde olarak ayarlarsanız, bu, "olayları işlenmiş olarak işaretleme" olarak adlandırılır. Yönlendirilmiş olayları, uygulama yazarı olarak veya var olan yönlendirilmiş olaylara yanıt veren bir denetim yazarı olarak veya yeni yönlendirilmiş olayları uygulayan bir denetim yazarı olarak işaretlemeniz gerektiğinde, için mutlak bir kural yoktur. Çoğu durumda, yönlendirilmiş olayın olay verilerinde gerçekleştirilen "işlenmiş" kavramının, kendi uygulamanızın, WPF API 'Lerinde sunulan çeşitli yönlendirilmiş olaylara ve özel yönlendirilmiş olaylara yönelik yanıtları için sınırlı bir protokol olarak kullanılması gerekir. "İşlenmiş" sorunu düşünmenin bir diğer yolu da, kodunuzun yönlendirilmiş olaya önemli ve görece bir şekilde yanıt vermesi durumunda, genellikle yönlendirilmiş bir olayı işaretlememesidir. 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, gerekli kod, iletmek üzere yönlendirilmiş olay sistemi kullanılarak değil, tek bir işleyici içinde zincirleme olan uygulama mantığı aracılığıyla uygulanmalıdır. "Önemli" ne olduğuna ilişkin kavram da öznel olur ve uygulamanıza veya kodunuza bağlıdır. Genel kılavuz olarak bazı "önemli yanıt" örnekleri şunlardır: odak ayarlama, genel durumu değiştirme, görsel temsili etkileyen özellikleri ayarlama ve diğer yeni olaylar oluşturma. Önemli olmayan yanıt örnekleri şunlardır: özel durumu değiştirme (görsel etki veya programlı gösterim olmadan), olayların günlüğe kaydedilmesi ya da bir olayın bağımsız değişkenlerine bakmak ve yanıt vermeyi tercih etmek.
Bu "önemli yanıt", XAML 'de eklenen işleyiciler veya ortak imzası, AddHandler olay verilerinin zaten işlenmiş olarak işaretlendiğinden yönlendirilmiş bir olaya yanıt olarak çağrılmadığından, yönlendirilmiş olay sistemi davranışı, bu "önemli yanıt" modelini yönlendirilmiş bir olayın işlenmiş durumunu kullanmak üzere zorlar. handledEventsTooAddHandler(RoutedEvent, Delegate, Boolean) Olay rotasında daha önceki katılımcılar tarafından işlenmiş olarak işaretlenen yönlendirilmiş olayları işlemek için parametre sürümü () olan bir işleyici eklemenin ek çabasına gitmeniz gerekir.
Bazı durumlarda denetimlerin kendilerine belirli yönlendirilmiş olayları işlenmiş olarak işaretlemesi. İşlenmiş bir yönlendirilmiş olay, WPF denetim yazarlarının, denetim uygulamasının bir parçası olarak önemli veya tamamlanmış olduğunu ve etkinliğin daha fazla işlem yapmasına ihtiyaç duymayacağını belirten bir karar temsil eder. Genellikle bu, bir olay için bir sınıf işleyici eklenerek veya bir temel sınıfta bulunan sınıf işleyici sanallaştırmadan birini geçersiz kılarak yapılır. Gerekirse bu olay işlemesini hala çözebilirsiniz; Bu konunun ilerleyen kısımlarında bulunan Denetim tarafından olay gizleme konusunda çalışma konusuna bakın.
"Önizleme" (tünel oluşturma) olayları ve kabarcıklanma olayları ve olay Işleme karşılaştırması
Yönlendirilmiş olayların önizlemesi, öğe ağacı aracılığıyla bir tünel yolunu izleyen olaylardır. Adlandırma kuralı 'nda ifade edilen "Önizleme", Önizleme (tünel) yönlendirilmiş olaylarının, eşdeğer kabarcıklanma yönlendirilmiş olayından önce ortaya çıkarılan giriş olayları için genel prensibi bir giriştir. Ayrıca, bir tünel oluşturma ve kabarcıklanma çiftinin bulunduğu giriş yönlendirilmiş olaylarının farklı bir işleme mantığı vardır. Tünel oluşturma/önizleme yönlendirilmiş olayı bir olay dinleyicisi tarafından işlenmiş olarak işaretlenmişse, kabarcıklanma yönlendirilmiş olayının herhangi bir dinleyicisi tarafından gönderilmeden önce kabarcıklanma yönlendirilmiş olayı işlenirler. Tünel oluşturma ve kabarcıklanma yönlendirilmiş olayları teknik açıdan ayrı olaylardır, ancak bu davranışı etkinleştirmek için aynı olay verisi örneğini kasıtlı olarak paylaşır.
Tünel oluşturma ve kabarcıklanma yönlendirilmiş olayları arasındaki bağlantı, belirli bir WPF sınıfının kendi kendilerine ait yönlendirilmiş olayları nasıl harekete geçirdiğine ilişkin iç uygulama tarafından gerçekleştirilir ve bu, eşleştirilmiş giriş yönlendirilmiş olaylarının doğru olması durumunda geçerlidir. Ancak, bu sınıf düzeyi uygulama mevcut değilse, tünel olarak yönlendirilen bir olay ve adlandırma şemasını paylaşan bir kabarcıklanma yönlendirilmiş olay arasında bağlantı yoktur: böyle bir uygulama olmadan, iki tamamen ayrı yönlendirilmiş olay olur ve sıralı veya olay verileri paylaşabilir.
Özel bir sınıfta tünel/kabarcık girişi yönlendirilmiş olay çiftlerinin nasıl uygulanacağı hakkında daha fazla bilgi için bkz. özel bir yönlendirilmiş olay oluşturma.
Sınıf Işleyicileri ve örnek Işleyicileri
Yönlendirilmiş olaylar, olaya iki farklı tür dinleyici düşünün: sınıf dinleyicileri ve örnek dinleyicileri. Türler belirli bir EventManager API 'yi, RegisterClassHandler , statik oluşturucularını veya bir öğe temel sınıfından bir sınıf işleyici sanal yöntemini geçersiz kıldığından, sınıf dinleyicileri vardır. Örnek dinleyicileri, bir veya daha fazla işleyicinin bu yönlendirilmiş olay için bir çağrısıyla eklendiği özel sınıf örneklerdir/öğelerdir AddHandler . Mevcut WPF yönlendirilmiş olayları, AddHandler ortak dil çalışma zamanı (CLR) olay sarmalayıcısı ' ın bir parçası olarak ' a çağrı yapar {} ve olay {} işleyicilerini bir öznitelik söz dizimi aracılığıyla ekleme basit XAML mekanizması etkin hale gelir. Bu nedenle, basit XAML kullanımı sonunda bir çağrıya karşılık gelir AddHandler .
Görsel ağaç içindeki öğeler, kayıtlı işleyici uygulamaları için denetlenir. İşleyiciler, bu yönlendirilmiş olay için yönlendirme stratejisinin türüne ait olan sırada yol genelinde çağrılabilir. Örneğin, kabarcıklanma yönlendirilmiş olayları ilk olarak, yönlendirilmiş olayı oluşturan öğeye bağlı olan işleyicileri çağırır. Ardından, yönlendirilmiş olay "kabarcıklar" bir sonraki üst öğeye ve bu nedenle uygulama kök öğesine ulaşılana kadar devam eder.
Bir kabarcıklanma rotasındaki kök öğenin perspektifinden, sınıf işleme veya herhangi bir öğe, olay bağımsız değişkenlerini işlendiği gibi işaretleyen yönlendirilmiş olay çağırma işleyicilerinin kaynağına yakınsa, kök öğelerdeki işleyiciler çağrılmaz ve olay yolu, bu kök öğeye ulaşmadan önce etkin bir şekilde kısaltıldı. Ancak, bir sınıf işleyicisi veya örnek işleyicisi, yönlendirilmiş olayı işlenmiş olarak işaretlese bile, işleyiciler, hala çağrılması gereken özel bir koşullu kullanılarak eklenebildiğinden, yol tamamen durdurulmaz. Bu, daha sonra bu konunun ilerleyen kısımlarında Olaylar Işlendiklerinde bile oluşturulan örnek Işleyicileri eklemebölümünde açıklanmaktadır.
Olay rotasına göre daha derin bir düzeyde, bir sınıfın belirli bir örneğinde çalışan büyük olasılıkla çok sayıda sınıf işleyicisi de vardır. Bunun nedeni, yönlendirilmiş olaylar için sınıf işleme modelinin her bir sınıf hiyerarşisindeki tüm olası sınıfların her bir yönlendirilmiş olay için kendi sınıf işleyicisine kaydolmalarını 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 hepsi olay yoluna eklenir. Sınıf işleyicileri rotaya, en çok türetilen sınıf işleyicisinin ilk çağrılmasından ve birbirini izleyen her taban sınıftan sınıf işleyicileri daha sonra çağrılır. Genellikle, sınıf işleyicileri, zaten işlenmiş olarak işaretlenmiş yönlendirilmiş olaylara yanıt vermek üzere kayıtlı değildir. Bu nedenle, bu sınıf işleme mekanizması iki seçenekten birini sunar:
Türetilmiş sınıflar, türetilmiş sınıf işleyiciden sonra bir zaman çağrıldığı için, yönlendirilmiş olayı ele alınmayan bir işleyici ekleyerek temel sınıftan devralınan sınıf işlemesini tamamlayabilir.
Türetilmiş sınıflar, işlenen olayı işaretleyen bir sınıf işleyicisi ekleyerek temel sınıftan sınıf işlemesini değiştirebilir. Görsel görünüm, durum mantığı, giriş işleme ve komut işleme gibi alanlarda amaçlanan temel denetim tasarımını değiştirebileceğinden, bu yaklaşım için dikkatli olmanız gerekir.
Denetim taban sınıflarına göre yönlendirilmiş olayların sınıf Işlemesi
Bir olay rotasında verilen her öğe düğümünde, sınıf dinleyicileri, öğe üzerindeki herhangi bir örnek dinleyicisine başlamadan önce yönlendirilmiş 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 istemeyen veya sınıfın bir özelliği olan bu yönlendirilmiş olayın özel işlemesini 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 anlamı hakkında daha fazla bilgi içeren kendi sınıfa özgü olayını oluşturabilir. Sınıf uygulama daha sonra, genel yönlendirilmiş olayı işlenmiş olarak işaretleyebilir. Sınıf işleyicileri genellikle paylaşılan olay verilerinin işlenmiş olarak işaretlenmiş olduğu yönlendirilmiş olaylar için çağrılmaması gibi eklenirler, ancak tipik durumlarda, RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) yönlendirilmiş olaylar işlenmiş olarak işaretlenmiş olsa bile, çağırmak üzere sınıf işleyicilerini kaydeden bir imza de vardır.
Sınıf Işleyici Sanallaştırals
Bazı öğeler, özellikle gibi temel öğeler UIElement , 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, bu yönlendirilmiş olay için bir sınıf işleyicisi uygulamak üzere geçersiz kılınabilir. Temel öğe sınıfları, RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) daha önce açıklandığı gibi kullanarak bu sanal yöntemleri, bu tür yönlendirilmiş olayların sınıf işleyicileri olarak kaydeder. On * olay 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 kolay hale getirir. Örneğin, DragEnterUIElement sanal yöntemi geçersiz kılarak türetilmiş herhangi bir sınıftaki olay için sınıf işleme ekleyebilirsiniz OnDragEnter . Geçersiz kılma içinde, yönlendirilmiş olayı işleyebilir, diğer olayları oluşturabilir, örneklerde öğe özelliklerini değiştirebilen sınıfa özgü mantık başlatabilir veya bu eylemlerin herhangi bir birleşimini kullanabilirsiniz. İşlenen olayı işaretleseniz bile, genellikle temel uygulamayı bu geçersiz kılmalarla çağırmanız gerekir. Sanal yöntem temel sınıfta olduğundan, temel uygulamayı çağırmak kesinlikle önerilir. Her bir sanal bilgisayardan temel uygulamaları çağırmanın standart korumalı sanal düzeni temelde, yönlendirilmiş olay sınıfı işlemeye yerel olan benzer bir mekanizmaya sahiptir ve paraleldir. bir sınıf hiyerarşisindeki tüm sınıflar için sınıf işleyicilerinin, en çok türetilmiş sınıf ' işleyicisiyle başlayarak ve temel sınıf işleyicisine devam eden herhangi bir örnek üzerinde çağrılması. Temel uygulama çağrısını yalnızca sınıfınızın temel sınıf işleme mantığını değiştirmek için bir bilinçli gereksinimi varsa atlayın. Geçersiz kılmadan önce veya sonra temel uygulamayı çağırdığınıza bakılmaksızın uygulamanızın yapısına bağlı olursunuz.
Giriş olayı sınıfı Işleme
Sınıf işleyici sanal yöntemlerinin tümü, yalnızca paylaşılan olay verilerinin zaten işlenmiş olarak işaretlenmediği durumlarda çağrılabilir. Ayrıca, giriş olayları için benzersiz olarak, tünel oluşturma ve köpürme sürümleri genellikle sırayla oluşturulur ve olay verilerini paylaşır. Bu, biri tünel oluşturma sürümü ve diğeri kabarcıklanma sürümü olan giriş olaylarının belirli bir çifti için, olayı hemen işlenmiş olarak işaretlemek istemeyebilirsiniz. İşlenen olayı işaretlemek için tünel oluşturma sınıfı işleme sanal yöntemini uygularsanız, bu, kabarcıklanma sınıfı işleyicisinin çağrılmasını engeller (Ayrıca, tünel veya kabarcıklanma olayının çağrılması için normal olarak kaydedilmiş örnek işleyicilerini önler).
Düğüm üzerinde sınıf işleme tamamlandıktan sonra, örnek dinleyicileri göz önünde bulundurulmalıdır.
Olaylar Işlendi olarak Işaretlendiğinde bile oluşturulan örnek Işleyicileri ekleme
AddHandlerYöntemi, başka bir işleyicinin bu olayı işlenmiş olarak işaretlemek için daha önce olay verilerini ayarlamış olsa bile olay sistemi tarafından çağrılacak işleyicileri eklemenize olanak sağlayan belirli bir aşırı yükleme sağlar. Bu genellikle yapılmaz. Genellikle, işleyiciler, birden fazla son sonuç istendiği halde bir öğe ağacında nerede işlendiğinin ne olursa olsun, bir olay tarafından etkilenmemiş olabilecek uygulama kodu alanlarının tüm bölümlerini ayarlamak için yazılabilir. Ayrıca, genellikle yalnızca bu olaya yanıt vermesi gereken bir öğe vardır ve uygun uygulama mantığı zaten gerçekleşiyordu. Ancak handledEventsToo aşırı yükleme, bir öğe ağacı veya denetim birleştirme içindeki başka bir öğenin zaten işlenmiş olarak bir olayı işaretlediği, ancak öğe ağacında daha yüksek veya daha düşük olan (rotaya bağlı olarak) diğer öğelerin kendi işleyicilerinin çağrılmasını istiyor.
Işlenmiş olayların ne zaman Işlenmemiş olarak Işaretleneceği
Genellikle, işlenmiş olarak işaretlenen yönlendirilmiş olaylar, üzerinde işlem gören işleyiciler tarafından bile işlenmemiş olarak işaretlenmemelidir ( Handled geri ayarlanmalıdır false ) handledEventsToo . Ancak, bazı giriş olayları, üst düzey olay ağaçta bir konumda ve alt düzey olay başka bir konumda görüldüğünde üst düzey ve alt düzey olay temsillerine sahiptir. Örneğin, bir alt öğenin, TextInput bir üst öğe gibi alt düzey bir olayı dinlediği gibi üst düzey bir anahtar olayına dinlediği durumu göz önünde bulundurun KeyDown . Üst öğe alt düzey olayı işlediğinde, daha üst düzey olay, daha yüksek olan alt öğede bile, olayı işlemeye yönelik ilk fırsata sahip olmalıdır.
Bu durumlarda, alt düzey olay için hem üst öğelere hem de alt öğelere işleyiciler eklemek gerekebilir. Alt öğe işleyicisi uygulama, düşük düzey olayı işlenmiş olarak işaretleyebilir, ancak üst öğe işleyicisi uygulamasının, ağacın (üst düzey olay) daha fazla öğenin yanıt vermesini sağlamak için yeniden işlenmemiş olarak ayarlanması gerekir. Bu durum oldukça nadir olmalıdır.
Denetim birleştirme için giriş olaylarını kasıtlı olarak gizleme
Yönlendirilmiş olayların sınıf işlemenin kullanıldığı ana senaryo, giriş olayları ve bileşik denetimler içindir. Ayrıştırılmış denetim, birden çok pratik denetimden veya denetim tabanlı sınıftan oluşan tanımdır. Genellikle denetimin yazarı her bir alt bileşeni tek bir olay kaynağı olarak raporlamak için, her bir alt bileşen tarafından her birinin tetiklenebilir tüm olası giriş olaylarını Amalgamate. Bazı durumlarda, denetim yazarı olayları tamamen ya da daha fazla bilgi içeren bileşen tanımlı bir olayı veya daha belirli bir davranışı ortaya koymak isteyebilir. herhangi bir bileşen yazarı için hemen görünür olan kurallı örnek, Windows Presentation Foundation (WPF), zaman zaman Button tüm düğmelerin sahip olduğu sezgisel bir olaya çözülecek herhangi bir fare olayını nasıl işleyeceğinden? Click
ButtonTemel sınıf ( ButtonBase ), ControlFrameworkElement ve ' den türettikten türetilir ve UIElement denetim girişi işleme için gereken olay altyapısının büyük bölümü düzeyinde kullanılabilir UIElement . Özellikle fare imleci için isabet testini kendi sınırları içinde ele alan genel olayları işler ve gibi en yaygın düğme eylemleri için UIElementMouse ayrı olaylar MouseLeftButtonDown sağlar. UIElement ayrıca için önceden kaydı OnMouseLeftButtonDown yapılan sınıf işleyicisi olarak boş bir sanal sağlar MouseLeftButtonDown ve bunu geçersiz ButtonBase kılar. Benzer şekilde, ButtonBase için sınıf işleyicilerini MouseLeftButtonUp kullanır. Olay verilerine geçirilen geçersiz kılmalarda, uygulamalar bu örneği olarak ayarlanarak işleyici olarak işaret eder ve aynı olay verileri, diğer sınıf işleyicilerine ve örnek işleyicilerine veya olay ayaricilerine giden yol boyunca devam eden aynı olay RoutedEventArgsHandledtrue verileridir. Ayrıca, geçersiz OnMouseLeftButtonUp kılma bundan sonra olayı Click yükseltecek. Dinleyicilerin çoğu için sonuç, ve olaylarının "kaybolması" ve yerine ile değiştirilmesidir. Bu olayın, düğmenin bileşik bir parçasından veya başka bir öğeden kaynaklandığı bilindiği için daha anlamlı olan bir MouseLeftButtonDownMouseLeftButtonUpClick olaydır.
Denetimler Tarafından Olay Gizleme ile Çalışma
Bazen tek tek denetimler içindeki bu olay gizleme davranışı, uygulamanıza göre olay işleme mantığının bazı genel amaçlarını etkileyene neden olabilir. Örneğin, herhangi bir nedenle, uygulamanın kök öğesinde yer alan bir işleyicisi varsa, bir düğmeye tıklarsanız kök düzeyinde herhangi bir fare tıklamanın veya işleyicileri MouseLeftButtonDownMouseLeftButtonDownMouseLeftButtonUp çağırmazsınız. Olayın kendisi gerçekten kabartı yaptı (yine olay yolları gerçekten sona ermiştir, ancak yönlendiren olay sistemi işlendi olarak işaretlendikten sonra işleyici çağırma davranışını değiştirir). Yönlendirilen olay düğmeye ulaşıldığında, sınıf işleme olayı daha anlamlı bir şekilde değiştirtme isteği ButtonBaseMouseLeftButtonDown nedeniyle Click işlenen'i işaretledi. Bu nedenle, yol MouseLeftButtonDown üzerinde daha fazla standart işleyici çağrılmaz. İşleyicinizin bu durumda çağrılması için kullanabileceğiniz iki teknik vardır.
İlk teknik, imzasını kullanarak işleyiciyi kasıtlı olarak handledEventsTooAddHandler(RoutedEvent, Delegate, Boolean) eklemektir. Bu yaklaşımın bir sınırlaması, olay işleyicisi ekleme tekniğinin işaretlemeden değil yalnızca koddan mümkün olduğudur. olay işleyicisi adını Extensible Application Markup Language (XAML) aracılığıyla olay özniteliği değeri olarak belirtmenin basit söz dizimi bu davranışı etkinleştirmez.
İkinci teknik yalnızca yönlendiren olayın tünel ve buyalı sürümlerinin eşleştirilmiş olduğu giriş olayları için çalışır. Bu yönlendirilen olaylar için, bunun yerine önizleme/tünel eşdeğer yönlendirilen olay için işleyiciler eklersiniz. Bu yönlendirilen olay kökten başlayarak yol üzerinden tüneller. Bu nedenle düğme sınıfı işleme kodu, önizleme işleyicisini uygulamanın öğe ağacına bir üst öğe düzeyinde iliştirmiş olduğunu kabul ediyordur. Bu yaklaşımı kullanıyorsanız, tüm Önizleme olaylarını işleme konusunda dikkatli olun. kök öğesinde işlenme ile verilen örnek için, olayı işleyici uygulamasında olduğu gibi işaretleyebilirsiniz, PreviewMouseLeftButtonDownHandled olayı gerçekten Click gizlemezsiniz. Bu genellikle tercih edilen bir davranış değildir.