WPF'deki Ağaçlar
Birçok teknolojide, öğeler ve bileşenler, geliştiricilerin bir uygulamanın işlenmesini veya davranışını etkilemek için ağaçtaki nesne düğümlerini doğrudan işlediği bir ağaç yapısında düzenlenir. Windows Presentation Foundation (WPF), program öğeleri arasındaki ilişkileri tanımlamak için çeşitli ağaç yapısı metaforları da kullanır. Çoğunlukla WPF geliştiricileri kodda bir uygulama oluşturabilir veya nesne ağacı metaforu hakkında kavramsal olarak düşünürken XAML'de uygulamanın bölümlerini tanımlayabilir, ancak XML DOM'da kullanabileceğiniz gibi bazı genel nesne ağacı işleme API'leri yerine belirli API'yi veya belirli işaretlemeleri çağıracak. WPF, bir ağaç metaforu görünümü sağlayan iki yardımcı sınıf olan LogicalTreeHelper ve VisualTreeHelper'i kullanıma sunar. Görsel ağaç ve mantıksal ağaç terimleri WPF belgelerinde de kullanılır çünkü bu ağaçlar belirli temel WPF özelliklerinin davranışını anlamak için yararlıdır. Bu konu görsel ağaç ve mantıksal ağacın neyi temsil yaptığını tanımlar, bu tür ağaçların genel bir nesne ağacı kavramıyla nasıl ilişkili olduğunu açıklar ve LogicalTreeHelper ve VisualTreeHelper'leri tanıtır.
WPF'deki Ağaçlar
WPF'deki en eksiksiz ağaç yapısı nesne ağacıdır. XAML'de bir uygulama sayfası tanımlar ve ardından XAML'yi yüklerseniz, ağaç yapısı işaretlemedeki öğelerin iç içe ilişkilerine göre oluşturulur. Kodda bir uygulama veya uygulamanın bir bölümünü tanımlarsanız, ağaç yapısı belirli bir nesne için içerik modelini uygulayan özellikler için özellik değerlerini nasıl atadığınıza bağlı olarak oluşturulur. WPF'de, nesne ağacının tamamının kavramsallaştırılıp genel API'sine raporlanabilmesinin iki yolu vardır: mantıksal ağaç ve görsel ağaç olarak. Mantıksal ağaç ve görsel ağaç arasındaki ayrımlar her zaman önemli değildir, ancak bazen bazı WPF alt sistemlerinde sorunlara neden olabilir ve işaretleme veya kodda yaptığınız seçimleri etkileyebilir.
Her zaman mantıksal ağacı veya görsel ağacı doğrudan işlemeseniz de, ağaçların etkileşim kurma kavramlarını anlamak WPF'yi bir teknoloji olarak anlamak için yararlıdır. WPF'yi bir tür ağaç metaforu olarak düşünmek, özellik devralma ve olay yönlendirmenin WPF'de nasıl çalıştığını anlamak için de çok önemlidir.
Not
Nesne ağacı gerçek bir API'den çok bir kavram olduğundan, kavramı düşünmenin başka bir yolu nesne grafıdır. Pratikte, çalışma zamanında nesneler arasında ağaç metaforunun parçalanacağı ilişkiler vardır. Bununla birlikte, özellikle XAML tanımlı kullanıcı arabiriminde ağaç metaforu, çoğu WPF belgesinin bu genel kavrama başvururken nesne ağacı terimini kullanacağı kadar ilgilidir.
Mantıksal Ağaç
WPF'de, bu öğeleri destekleyen nesnelerin özelliklerini ayarlayarak ui öğelerine içerik eklersiniz. Örneğin, Items özelliğini düzenleyerek bir ListBox denetimine öğeler eklersiniz. Bunu yaptığınızda, ItemCollection öğelerini Items özellik değeri olan yere yerleştirirsiniz. Benzer şekilde, bir DockPanelnesne eklemek için Children özellik değerini işleyebilirsiniz. Burada, UIElementCollection'a nesneler ekliyorsunuz. Kod örneği için bkz. Nasıl yapılır:Dinamik Olarak Öğe Ekleme.
Genişletilebilir Uygulama Biçimlendirme Dili'nde (XAML) liste öğelerini bir ListBox veya denetimlere ya da DockPaneldiğer ui öğelerine yerleştirdiğinizde, aşağıdaki örnekte olduğu gibi Items ve Children özelliklerini de açıkça veya örtük olarak kullanırsınız.
<DockPanel
Name="ParentElement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<!--implicit: <DockPanel.Children>-->
<ListBox DockPanel.Dock="Top">
<!--implicit: <ListBox.Items>-->
<ListBoxItem>
<TextBlock>Dog</TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock>Cat</TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock>Fish</TextBlock>
</ListBoxItem>
<!--implicit: </ListBox.Items>-->
</ListBox>
<Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>
<!--implicit: </DockPanel.Children>-->
</DockPanel>
Bu XAML'yi belge nesnesi modeli altında XML olarak işlemiş olsaydınız ve etkinleştirilmemiş olarak açıklamalara dahil ettiğiniz etiketleri eklemiş olsaydınız (bu yasal olabilirdi), o zaman ortaya çıkan XML DOM ağacı, <ListBox.Items>
ve diğer örtük öğeler için öğeler içeriyor olurdu. Ancak işaretlemeyi okuduğunuzda ve nesnelere yazdığınızda XAML bu şekilde işlemez, sonuçta elde edilen nesne grafı tam olarak ListBox.Items
içermez. Ancak, Items
adlı ve ItemCollectioniçeren bir ListBox özelliği vardır; ItemCollection ise başlatılmış fakat ListBox XAML işlendiğinde boş durumda olur. Ardından, ListBox'ın içeriği olarak var olan her alt nesne öğesi, ItemCollection.Add
'ye yapılan ayrıştırıcı çağrılarıyla ItemCollection'e eklenir. XAML'yi nesne ağacına işlemeye ilişkin bu örnek, oluşturulan nesne ağacının temelde mantıksal ağaç olduğu bir örnek gibi görünüyor.
Ancak mantıksal ağaç, XAML örtük söz dizimi öğelerinin dikkate alınmadığı durumlarda bile çalışma zamanında uygulama kullanıcı arabiriminiz için var olan nesne grafiğinin tamamı değildir. Bunun temel nedeni görseller ve şablonlardır. Örneğin, Buttongöz önünde bulundurun. Mantıksal ağaç, Button nesnesini ve Content
dizesini raporlar. Ancak çalışma zamanı nesne ağacında bu düğmeyle ilgili daha fazlası bulunur. Özellikle, düğme yalnızca belirli bir Button denetim şablonu uygulandığından ekranda göründüğü gibi görünür. Uygulanan bir şablondan gelen görseller (görsel düğmesinin etrafındaki şablon tanımlı Border koyu gri gibi), çalışma zamanında mantıksal ağaca bakıyor olsanız bile (görünür kullanıcı arabiriminden bir giriş olayını işleme ve mantıksal ağacı okuma gibi) mantıksal ağaçta raporlanmaz. Şablon görsellerini bulmak için bunun yerine görsel ağacı incelemeniz gerekir.
XAML söz diziminin oluşturulan nesne grafı ile nasıl eşleştiği ve XAML'deki örtük söz dizimi hakkında daha fazla bilgi için bkz. XAML Söz Dizimi Ayrıntılı veya WPF’de XAML.
Mantıksal Ağacın Amacı
Mantıksal ağaç, içerik modellerinin olası alt nesneleri üzerinde kolayca yinelenebilmesini ve böylece içerik modellerinin genişletilebilir olmasını sağlar. Ayrıca mantıksal ağaç, mantıksal ağaçtaki tüm nesnelerin yüklendiği durumlar gibi belirli bildirimler için bir çerçeve sağlar. Temel olarak, mantıksal ağaç, çalışma zamanı nesne grafiğinin çerçeve düzeyinde görselleri dışlayan bir yaklaşık değeridir, ancak kendi çalışma zamanı uygulamanızın bileşimine göre birçok sorgulama işlemi için yeterlidir.
Buna ek olarak, hem statik hem de dinamik kaynak başvuruları, ilk isteği yapan nesnenin Resources koleksiyonları için mantıksal ağaçta yukarı bakılarak, ardından mantıksal ağaçta yukarı doğru devam edilerek ve her FrameworkElement (veya FrameworkContentElement) içinde büyük olasılıkla bu anahtarı içeren bir ResourceDictionaryiçeren başka bir Resources
değeri olup olmadığını denetleyerek belirlenir. Mantıksal ağaç, hem mantıksal ağaç hem de görsel ağaç mevcut olduğunda kaynak arama için kullanılır. Kaynak sözlükleri ve arama hakkında daha fazla bilgi için bkz. XAML Kaynakları.
Mantıksal Ağacın Bileşimi
Mantıksal ağaç WPF çerçeve düzeyinde tanımlanır; bu da mantıksal ağaç işlemleri için en uygun WPF temel öğesinin FrameworkElement veya FrameworkContentElementolduğu anlamına gelir. Ancak, LogicalTreeHelper API'sini gerçekten kullanıp kullanmayabileceğinizi görebileceğiniz gibi, mantıksal ağaç bazen FrameworkElement veya FrameworkContentElementolmayan düğümler içerir. Örneğin, mantıksal ağaç, bir dize olan TextBlock'in Text değerini raporlar.
Mantıksal Ağacı Geçersiz Kılma
Gelişmiş denetim yazarları, genel bir nesnenin veya içerik modelinin mantıksal ağaç içindeki nesneleri nasıl eklediğini veya kaldırdığını tanımlayan birkaç API'yi geçersiz kılarak mantıksal ağacı geçersiz kılabilir. Mantıksal ağacı geçersiz kılma örneği için bkz. Mantıksal Ağaçgeçersiz kılma.
Özellik Değeri Devralma
Özellik değeri devralma, karma bir ağaç üzerinden çalışır. Özellik devralmayı etkinleştiren Inherits özelliğini içeren gerçek meta veriler WPF çerçeve düzeyi FrameworkPropertyMetadata sınıfıdır. Bu nedenle, hem özgün değeri tutan üst öğe hem de bu değeri devralan alt nesne FrameworkElement veya FrameworkContentElementolmalıdır ve her ikisi de bir mantıksal ağacın parçası olmalıdır. Ancak, özellik devralmayı destekleyen mevcut WPF özellikleri için, özellik değeri devralma, mantıksal ağaca dahil olmayan, araya giren bir nesne aracılığıyla da devam edebilir. Temel olarak bu, şablon öğelerinin, şablonlanmış örnek üzerinde veya daha yüksek sayfa düzeyindeki kompozisyon katmanlarında ve dolayısıyla mantıksal ağaçta daha üst seviyelerde ayarlanmış olan devralınmış özellik değerlerini kullanabilmesini sağlamak içindir. Özellik değeri devralma işleminin böyle bir sınırda tutarlı bir şekilde çalışması için devralan özelliğin ekli özellik olarak kaydedilmesi gerekir ve özellik devralma davranışıyla özel bir bağımlılık özelliği tanımlamayı planlıyorsanız bu deseni izlemeniz gerekir. Özellik devralma için kullanılan tam ağaç, çalışma zamanında bile yardımcı sınıf yardımcı programı yöntemi tarafından tam olarak tahmin edilemez. Daha fazla bilgi için bkz. Özellik Değeri Devralma.
Görsel Ağaç
Mantıksal ağaç kavramına ek olarak WPF'de görsel ağaç kavramı da vardır. Görsel ağaç, Visual temel sınıfı tarafından gösterildiği gibi görsel nesnelerin yapısını açıklar. Bir denetim için şablon yazarken, bu denetim için geçerli olan görsel ağacı tanımlar veya yeniden tanımlarsınız. Görsel ağaç, performans ve iyileştirme nedenleriyle çizim üzerinde daha düşük düzeyde denetim sahibi olmak isteyen geliştiriciler için de ilgi çekicidir. Geleneksel WPF uygulama programlamasının bir parçası olarak, görsel ağacın sunduğu özelliklerden biri, yönlendirilen bir olay için, olay yollarının çoğunlukla mantıksal ağaç yerine görsel ağaç boyunca izlenmesidir. Denetim yazarı olmadığınız sürece yönlendirilmiş olay davranışının bu inceliği hemen görülmeyebilir. Olayları görsel ağaç üzerinden yönlendirmek, olayları işlemek veya olay ayarlayıcıları oluşturmak için görsel düzeyinde oluşturma uygulayan denetimleri etkinleştirir.
Ağaçlar, İçerik Öğeleri ve İçerik Konakları
İçerik öğeleri (ContentElement' den türetilen sınıflar) görsel ağacın parçası değildir; Visual devralmıyor ve görsel bir gösterimi yok. Bir kullanıcı arayüzünde görünmek için, ContentElement'un hem Visual hem de mantıksal ağaç katılımcısı olan bir içerik sunucusunda barındırılması gerekir. Genellikle böyle bir nesne FrameworkElementolarak kullanılır. İçerik sunucusunun, içeriği bir "tarayıcı" gibi kısmen kontrol ettiğini ve bu içeriğin sunucunun denetimindeki ekran bölgesinde nasıl görüntüleneceğine karar verdiğini düşünebilirsiniz. İçerik barındırıldığında, içerik tipik olarak görsel ağaçla bağlantılı olan belirli ağaç işlemlerine katılımcı yapılabilir. Genellikle FrameworkElement konak sınıfı, barındırılan içerik gerçek görsel ağacının parçası olmasa bile içerik mantıksal ağacının alt düğümleri aracılığıyla olay yoluna barındırılan ContentElement ekleyen uygulama kodunu içerir. Bu, bir ContentElement'ın kendisinin dışında başka bir öğeye yönlendirilebilecek bir olay kaynaklaması için gereklidir.
Ağaç Geçişi
LogicalTreeHelper sınıfı, mantıksal ağaç geçişi için GetChildren, GetParentve FindLogicalNode yöntemlerini sağlar. Çoğu durumda, mevcut denetimlerin mantıksal ağacında gezinmeniz gerekmez çünkü bu denetimler neredeyse her zaman mantıksal alt öğelerini, Add
gibi koleksiyon erişimini, dizinleyiciyi ve benzeri özellikleri destekleyen özel bir koleksiyon özelliği olarak sunar. Ağaç geçişi temel olarak, koleksiyon özelliklerinin zaten tanımlandığı ItemsControl veya Panel gibi hedeflenen denetim desenlerinden türetmemeyi seçen ve kendi koleksiyon özelliği desteğini sağlamayı amaçlayan denetim yazarları tarafından kullanılan bir senaryodur.
Görsel ağaç, görsel ağaç geçişi için VisualTreeHelpergibi yardımcı bir sınıfı da destekler. Görsel ağaç denetime özgü özellikler aracılığıyla rahatça gösterilmez, bu nedenle VisualTreeHelper sınıfı, programlama senaryonuz için gerekliyse görsel ağaçtan geçiş yapmak için önerilen yoldur. Daha fazla bilgi için bkz. WPF Grafik İşlemeye Genel Bakış.
Not
Bazen uygulanan bir şablonun görsel ağacını incelemek gerekir. Bu tekniği kullanırken dikkatli olmalısınız. Şablonu tanımladığınız bir denetim için görsel ağaçtan geçseniz bile, denetiminizin tüketicileri her zaman örneklerde Template özelliğini ayarlayarak şablonu değiştirebilir ve hatta son kullanıcı bile sistem temasını değiştirerek uygulanan şablonu etkileyebilir.
Yönlendirilmiş Olaylar için "Ağaç" Olarak Rotalar
Daha önce belirtildiği gibi, belirli bir yönlendirilmiş olayın yolu, görsel ve mantıksal ağaç gösterimlerinin karması olan bir ağacın tek ve önceden belirlenmiş yolu boyunca ilerler. Olay rotası, tünelleme veya kabarcıklanma yönlendirilmiş olay olmasına bağlı olarak ağaç içinde yukarı veya aşağı yönde ilerleyebilir. Olay yolu kavramı, aslında yönlendirilecek bir olay oluşturmaktan bağımsız olarak, olay rotasında "ilerlemek" için kullanılabilecek doğrudan destekleyici bir yardımcı sınıfa sahip değildir. EventRouteyolunu temsil eden bir sınıf vardır, ancak bu sınıfın yöntemleri genellikle yalnızca iç kullanım içindir.
Kaynak Sözlükleri ve Ağaçlar
Bir sayfada tanımlanan tüm Resources
için kaynak sözlüğü araması temel olarak mantıksal ağaçtan geçiş sağlar. Mantıksal ağaçta olmayan nesneler anahtarlı kaynaklara başvurabilir, ancak kaynak arama dizisi bu nesnenin mantıksal ağaca bağlandığı noktada başlar. WPF'de, yalnızca mantıksal ağaç düğümleri ResourceDictionaryiçeren bir Resources
özelliğine sahip olabilir, bu nedenle ResourceDictionaryanahtarlı kaynakları aramak için görsel ağaçtan geçmenin bir yararı yoktur.
Ancak kaynak arama işlemi, anlık mantıksal ağacın ötesine de yayılabilir. Uygulama işaretlemesi için, kaynak arama işlemi, uygulama düzeyindeki kaynak sözlüklerine ve ardından statik özellikler veya anahtarlar olarak belirtilen tema desteği ile sistem değerlerine doğru ilerlemeye devam edebilir. Kaynak başvuruları dinamikse temaların kendileri de tema mantıksal ağacının dışındaki sistem değerlerine başvurabilir. Kaynak sözlükleri ve arama mantığı hakkında daha fazla bilgi için bkz. XAML Kaynakları.
Ayrıca bkz.
- Girişe Genel Bakış
- WPF Grafik İşlemeye Genel Bakış
- Yönlendirilen Olaylara Genel Bakış
- Nesne Ağacında Olmayan Nesne Öğeleri için Başlatma
- WPF Mimarisi
.NET Desktop feedback