Bagikan melalui


Pohon di WPF

Dalam banyak teknologi, elemen dan komponen diatur dalam struktur pohon di mana pengembang secara langsung memanipulasi simpul objek di pohon untuk memengaruhi penyajian atau perilaku aplikasi. Windows Presentation Foundation (WPF) juga menggunakan beberapa metafora struktur pohon untuk menentukan hubungan antar elemen program. Untuk sebagian besar pengembang WPF dapat membuat aplikasi dalam kode atau menentukan bagian aplikasi di XAML sambil berpikir secara konseptual tentang metafora pohon objek, tetapi akan memanggil API tertentu atau menggunakan markup tertentu untuk melakukannya daripada beberapa API manipulasi pohon objek umum seperti yang mungkin Anda gunakan di XML DOM. WPF mengekspos dua kelas pembantu yang memberikan tampilan metafora pohon, LogicalTreeHelper dan VisualTreeHelper. Istilah pohon visual dan pohon logis juga digunakan dalam dokumentasi WPF karena pohon yang sama ini berguna untuk memahami perilaku fitur WPF kunci tertentu. Topik ini mendefinisikan apa yang diwakili pohon visual dan pohon logis, membahas bagaimana pohon tersebut berhubungan dengan konsep pohon objek keseluruhan, dan memperkenalkan LogicalTreeHelper dan VisualTreeHelpers.

Pohon di WPF

Struktur pohon yang paling lengkap di WPF adalah pohon objek. Jika Anda menentukan halaman aplikasi di XAML lalu memuat XAML, struktur pohon dibuat berdasarkan hubungan berlapis elemen dalam markup. Jika Anda menentukan aplikasi atau sebagian aplikasi dalam kode, struktur pohon dibuat berdasarkan cara Anda menetapkan nilai properti untuk properti yang mengimplementasikan con mode tenda l untuk objek tertentu. Di WPF, ada dua cara agar pohon objek lengkap dikonsep dan dapat dilaporkan ke API publiknya: sebagai pohon logis dan sebagai pohon visual. Perbedaan antara pohon logis dan pohon visual tidak selalu penting, tetapi kadang-kadang dapat menyebabkan masalah dengan subsistem WPF tertentu dan memengaruhi pilihan yang Anda buat dalam markup atau kode.

Meskipun Anda tidak selalu memanipulasi pohon logis atau pohon visual secara langsung, memahami konsep bagaimana pohon berinteraksi berguna untuk memahami WPF sebagai teknologi. Memikirkan WPF sebagai metafora pohon dari beberapa jenis juga penting untuk memahami bagaimana warisan properti dan perutean peristiwa bekerja di WPF.

Catatan

Karena pohon objek lebih merupakan konsep daripada API aktual, cara lain untuk memikirkan konsep adalah sebagai grafik objek. Dalam praktiknya, ada hubungan antara objek pada run time di mana metafora pohon akan rusak. Namun demikian, terutama dengan UI yang ditentukan XAML, metafora pohon cukup relevan sehingga sebagian besar dokumentasi WPF akan menggunakan istilah pohon objek saat mereferensikan konsep umum ini.

Pohon Logis

Di WPF, Anda menambahkan konten ke elemen UI dengan mengatur properti objek yang mendukung elemen tersebut. Misalnya, Anda menambahkan item ke ListBox kontrol dengan memanipulasi propertinya Items . Dengan melakukan ini, Anda menempatkan item ke ItemCollection dalam yang merupakan Items nilai properti. Demikian pula, untuk menambahkan objek ke DockPanel, Anda memanipulasi nilai propertinya Children . Di sini, Anda menambahkan objek ke UIElementCollection. Untuk contoh kode, lihat Cara: Menambahkan Elemen Secara Dinamis.

Dalam Extensible Application Markup Language (XAML), saat Anda menempatkan item daftar dalam ListBox kontrol atau atau elemen UI lainnya dalam DockPanel, Anda juga menggunakan Items properti dan Children , baik secara eksplisit maupun implisit, seperti dalam contoh berikut.

<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>

Jika Anda memproses XAML ini sebagai XML di bawah model objek dokumen, dan jika Anda telah menyertakan tag yang dikomentari sebagai implisit (yang akan legal), pohon XML DOM yang dihasilkan akan menyertakan elemen untuk <ListBox.Items> dan item implisit lainnya. Tetapi XAML tidak memproses seperti itu ketika Anda membaca markup dan menulis ke objek, grafik objek yang dihasilkan tidak secara harfiah menyertakan ListBox.Items. Namun, ia memiliki ListBox properti bernama Items yang berisi ItemCollection, dan yang ItemCollection diinisialisasi tetapi kosong ketika ListBox XAML diproses. Kemudian, setiap elemen objek anak yang ada sebagai konten untuk ListBox ditambahkan ke ItemCollection panggilan pengurai ke ItemCollection.Add. Contoh pemrosesan XAML ini ke dalam pohon objek sejauh ini tampaknya merupakan contoh di mana pohon objek yang dibuat pada dasarnya adalah pohon logis.

Namun, pohon logis bukan seluruh grafik objek yang ada untuk UI aplikasi Anda pada waktu proses, bahkan dengan item sintaksis implisit XAML diperhitungkan. Alasan utama untuk ini adalah visual dan templat. Misalnya, pertimbangkan Button. Pohon logis melaporkan Button objek dan juga string-nya Content. Tetapi ada lebih banyak tombol ini di pohon objek run-time. Secara khusus, tombol hanya muncul di layar seperti yang dilakukannya karena templat kontrol tertentu Button diterapkan. Visual yang berasal dari templat yang diterapkan (seperti yang ditentukan Border templat berwarna abu-abu gelap di sekitar tombol visual) tidak dilaporkan di pohon logis, bahkan jika Anda melihat pohon logis selama run time (seperti menangani peristiwa input dari UI yang terlihat dan kemudian membaca pohon logis). Untuk menemukan visual templat, Anda harus memeriksa pohon visual.

Untuk informasi selengkapnya tentang cara sintaks XAML memetakan ke grafik objek yang dibuat, dan sintaks implisit dalam XAML, lihat Sintaks XAML Secara Rinci atau XAML di WPF.

Tujuan Pohon Logis

Pohon logis ada sehingga con mode tenda ls dapat dengan mudah melakukan iterasi atas kemungkinan objek anak mereka, dan sehingga con mode tenda ls dapat diperluas. Selain itu, pohon logis menyediakan kerangka kerja untuk pemberitahuan tertentu, seperti ketika semua objek di pohon logis dimuat. Pada dasarnya, pohon logis adalah perkiraan grafik objek run time di tingkat kerangka kerja, yang mengecualikan visual, tetapi memadai untuk banyak operasi kueri terhadap komposisi aplikasi run time Anda sendiri.

Selain itu, referensi sumber daya statis dan dinamis diselesaikan dengan mencari ke atas melalui pohon logis untuk Resources koleksi pada objek permintaan awal, dan kemudian melanjutkan pohon logis dan memeriksa masing-masing FrameworkElement (atau FrameworkContentElement) untuk nilai lain Resources yang berisi ResourceDictionary, mungkin berisi kunci tersebut. Pohon logis digunakan untuk pencarian sumber daya ketika pohon logis dan pohon visual ada. Untuk informasi selengkapnya tentang kamus dan pencarian sumber daya, lihat Sumber Daya XAML.

Komposisi Pohon Logis

Pohon logis didefinisikan pada tingkat kerangka kerja WPF, yang berarti bahwa elemen dasar WPF yang paling relevan untuk operasi pohon logis adalah FrameworkElement atau FrameworkContentElement. Namun, seperti yang Anda lihat jika Anda benar-benar menggunakan LogicalTreeHelper API, pohon logis terkadang berisi simpul yang bukan FrameworkElement atau FrameworkContentElement. Misalnya, pohon logis melaporkan Text nilai TextBlock, yang merupakan string.

Mengesampingkan Pohon Logis

Penulis kontrol tingkat lanjut dapat mengambil alih pohon logis dengan mengesampingkan beberapa API yang menentukan bagaimana objek umum atau con mode tenda l menambahkan atau menghapus objek di dalam pohon logis. Untuk contoh cara mengambil alih pohon logis, lihat Mengambil alih Pohon Logis.

Warisan Nilai Properti

Warisan nilai properti beroperasi melalui pohon hibrid. Metadata aktual yang berisi Inherits properti yang memungkinkan pewarisan properti adalah kelas tingkat FrameworkPropertyMetadata kerangka kerja WPF. Oleh karena itu, induk yang memegang nilai asli dan objek anak yang mewarisi nilai tersebut harus FrameworkElement atau FrameworkContentElement, dan keduanya harus menjadi bagian dari beberapa pohon logis. Namun, untuk properti WPF yang ada yang mendukung pewarisan properti, warisan nilai properti dapat mewarisi melalui objek intervensi yang tidak ada di pohon logis. Terutama ini relevan untuk memiliki elemen templat menggunakan nilai properti yang diwariskan yang ditetapkan baik pada instans yang di-template, atau pada tingkat komposisi tingkat halaman yang masih lebih tinggi dan karenanya lebih tinggi di pohon logis. Agar pewarisan nilai properti berfungsi secara konsisten di seluruh batas seperti itu, properti warisan harus didaftarkan sebagai properti terlampir, dan Anda harus mengikuti pola ini jika Anda ingin menentukan properti dependensi kustom dengan perilaku warisan properti. Pohon yang tepat yang digunakan untuk warisan properti tidak dapat sepenuhnya diantisipasi oleh metode utilitas kelas pembantu, bahkan pada waktu proses. Untuk informasi selengkapnya, lihat Pewarisan Nilai Properti.

Pohon Visual

Selain konsep pohon logis, ada juga konsep pohon visual di WPF. Pohon visual menjelaskan struktur objek visual, seperti yang Visual diwakili oleh kelas dasar. Saat Anda menulis templat untuk kontrol, Anda menentukan atau mendefinisikan ulang pohon visual yang berlaku untuk kontrol tersebut. Pohon visual juga menarik bagi pengembang yang menginginkan kontrol tingkat bawah atas gambar karena alasan performa dan pengoptimalan. Salah satu paparan pohon visual sebagai bagian dari pemrograman aplikasi WPF konvensional adalah bahwa rute peristiwa untuk peristiwa yang dirutekan sebagian besar melakukan perjalanan di sepanjang pohon visual, bukan pohon logis. Kelemahan perilaku peristiwa yang dirutekan ini mungkin tidak segera terlihat kecuali Anda adalah penulis kontrol. Merutekan peristiwa melalui pohon visual memungkinkan kontrol yang menerapkan komposisi di tingkat visual untuk menangani peristiwa atau membuat setter peristiwa.

Pohon, Elemen Konten, dan Host Konten

Elemen konten (kelas yang berasal dari ContentElement) bukan bagian dari pohon visual; elemen tersebut tidak mewarisi dari Visual dan tidak memiliki representasi visual. Untuk muncul di UI sama sekali, ContentElement harus dihosting di host konten yang merupakan Visual peserta pohon logis dan . Biasanya objek seperti itu adalah FrameworkElement. Anda dapat mengonsepkan bahwa host konten agak seperti "browser" untuk konten dan memilih cara menampilkan konten tersebut dalam wilayah layar yang dikontrol host. Ketika konten dihosting, konten dapat dijadikan peserta dalam proses pohon tertentu yang biasanya terkait dengan pohon visual. Umumnya, FrameworkElement kelas host menyertakan kode implementasi yang menambahkan apa pun yang dihosting ContentElement ke rute peristiwa melalui subnode pohon logis konten, meskipun konten yang dihosting bukan bagian dari pohon visual sejati. Ini diperlukan agar ContentElement dapat sumber peristiwa yang dirutekan yang dirutekan ke elemen apa pun selain dirinya sendiri.

Tree Traversal

Kelas ini LogicalTreeHelper menyediakan metode , GetParent, dan FindLogicalNode untuk traversal GetChildrenpohon logis. Dalam kebanyakan kasus, Anda tidak perlu melintasi pohon logis kontrol yang ada, karena kontrol ini hampir selalu mengekspos elemen anak logis mereka sebagai properti koleksi khusus yang mendukung akses pengumpulan seperti , pengindeks, dan sebagainya Add. Tree traversal terutama merupakan skenario yang digunakan oleh penulis kontrol yang memilih untuk tidak berasal dari pola kontrol yang dimaksudkan seperti ItemsControl atau Panel di mana properti pengumpulan sudah ditentukan, dan siapa yang berniat untuk memberikan dukungan properti koleksi mereka sendiri.

Pohon visual juga mendukung kelas pembantu untuk traversal pohon visual, VisualTreeHelper. Pohon visual tidak diekspos dengan nyaman melalui properti khusus kontrol, jadi VisualTreeHelper kelas adalah cara yang disarankan untuk melintasi pohon visual jika diperlukan untuk skenario pemrograman Anda. Untuk informasi selengkapnya, lihat Gambaran Umum Penyajian Grafis WPF.

Catatan

Terkadang perlu untuk memeriksa pohon visual templat yang diterapkan. Anda harus berhati-hati saat menggunakan teknik ini. Bahkan jika Anda melintasi pohon visual untuk kontrol tempat Anda menentukan templat, konsumen kontrol Anda selalu dapat mengubah templat dengan mengatur Template properti pada instans, dan bahkan pengguna akhir dapat memengaruhi templat yang diterapkan dengan mengubah tema sistem.

Rute untuk Peristiwa Yang Dirutekan sebagai "Pohon"

Seperti disebutkan sebelumnya, rute peristiwa yang dirutekan tertentu berjalan di sepanjang satu dan jalur pohon yang telah ditentukan yang merupakan hibrida dari representasi pohon visual dan logis. Rute peristiwa dapat melakukan perjalanan baik ke arah atas atau bawah di dalam pohon tergantung pada apakah itu peristiwa terowongan atau menggelegak yang dirutekan. Konsep rute peristiwa tidak memiliki kelas pembantu pendukung langsung yang dapat digunakan untuk "berjalan" rute peristiwa secara independen dari menaikkan peristiwa yang benar-benar rute. Ada kelas yang mewakili rute, EventRoute, tetapi metode kelas tersebut umumnya hanya untuk penggunaan internal.

Kamus dan Pohon Sumber Daya

Pencarian kamus sumber daya untuk semua Resources yang ditentukan dalam halaman melintasi pada dasarnya pohon logis. Objek yang tidak berada di pohon logis dapat mereferensikan sumber daya yang di-key, tetapi urutan pencarian sumber daya dimulai pada titik di mana objek tersebut terhubung ke pohon logis. Di WPF, hanya simpul pohon logis yang dapat memiliki Resources properti yang berisi ResourceDictionary, oleh karena itu tidak ada manfaat dalam melintas pohon visual yang mencari sumber daya kunci dari ResourceDictionary.

Namun, pencarian sumber daya juga dapat meluas di luar pohon logis langsung. Untuk markup aplikasi, pencarian sumber daya kemudian dapat dilanjutkan ke kamus sumber daya tingkat aplikasi dan kemudian ke dukungan tema dan nilai sistem yang dirujuk sebagai properti statis atau kunci. Tema itu sendiri juga dapat mereferensikan nilai sistem di luar pohon logis tema jika referensi sumber daya dinamis. Untuk informasi selengkapnya tentang kamus sumber daya dan logika pencarian, lihat Sumber Daya XAML.

Baca juga