Bagikan melalui


Ekstensi Markup dan WPF XAML

Topik ini memperkenalkan konsep ekstensi markup untuk XAML, termasuk aturan sintaks, tujuan, dan model objek kelas yang mendasarnya. Ekstensi markup adalah fitur umum dari bahasa XAML dan implementasi .NET layanan XAML. Topik ini secara khusus merinci ekstensi markup untuk digunakan dalam WPF XAML.

Prosesor XAML dan Ekstensi Markup

Secara umum, pengurai XAML dapat menginterpretasikan nilai atribut sebagai string harfiah yang dapat dikonversi menjadi primitif, atau mengonversinya menjadi objek dengan beberapa cara. Salah satu cara tersebut adalah dengan mereferensikan pengonversi jenis; ini didokumenkan dalam topik TypeConverters dan XAML. Namun, ada skenario di mana perilaku yang berbeda diperlukan. Misalnya, prosesor XAML dapat diinstruksikan bahwa nilai atribut tidak boleh menghasilkan objek baru dalam grafik objek. Sebaliknya, atribut harus menghasilkan grafik objek yang membuat referensi ke objek yang sudah dibangun di bagian lain dari grafik, atau objek statis. Skenario lain adalah bahwa prosesor XAML dapat diinstruksikan untuk menggunakan sintaks yang menyediakan argumen non-default ke konstruktor objek. Ini adalah jenis skenario di mana ekstensi markup dapat memberikan solusi.

Sintaks Ekstensi Markup Dasar

Ekstensi markup dapat diimplementasikan untuk menyediakan nilai untuk properti dalam penggunaan atribut, properti dalam penggunaan elemen properti, atau keduanya.

Ketika digunakan untuk memberikan nilai atribut, sintaks yang membedakan urutan ekstensi markup ke prosesor XAML adalah adanya kurung kurawal pembuka dan penutupan kurawal ({ dan }). Jenis ekstensi markup kemudian diidentifikasi oleh token string segera setelah kurung kurawal pembuka.

Saat digunakan dalam sintaks elemen properti, ekstensi markup secara visual sama dengan elemen lain yang digunakan untuk memberikan nilai elemen properti: deklarasi elemen XAML yang mereferensikan kelas ekstensi markup sebagai elemen, yang diapit dalam tanda kurung sudut (<>).

Ekstensi Markup yang Ditentukan XAML

Ada beberapa ekstensi markup yang tidak spesifik untuk implementasi WPF XAML, tetapi sebaliknya merupakan implementasi intrinsik atau fitur XAML sebagai bahasa. Ekstensi markup ini diimplementasikan dalam rakitan System.Xaml sebagai bagian dari layanan XAML .NET Framework umum, dan berada dalam namespace XAML bahasa XAML. Dalam hal penggunaan markup umum, ekstensi markup ini biasanya dapat diidentifikasi oleh x: awalan dalam penggunaan. Kelas MarkupExtension dasar (juga didefinisikan dalam System.Xaml) menyediakan pola yang harus digunakan semua ekstensi markup agar dapat didukung di pembaca XAML dan penulis XAML, termasuk dalam WPF XAML.

  • x:TypeType memasok objek untuk jenis bernama. Fasilitas ini paling sering digunakan dalam gaya dan templat. Untuk detailnya, lihat x:Type Markup Extension.

  • x:Static menghasilkan nilai statis. Nilai berasal dari entitas kode jenis nilai yang tidak secara langsung merupakan jenis nilai properti target, tetapi dapat dievaluasi ke jenis tersebut. Untuk detailnya, lihat x:Static Markup Extension.

  • x:Nullnull menentukan sebagai nilai untuk properti dan dapat digunakan baik untuk atribut atau nilai elemen properti. Untuk detailnya, lihat x:Null Markup Extension.

  • x:Array menyediakan dukungan untuk pembuatan array umum dalam sintaks XAML, untuk kasus di mana dukungan koleksi yang disediakan oleh elemen dasar WPF dan model kontrol sengaja tidak digunakan. Untuk detailnya, lihat x:Array Markup Extension.

Catatan

x: Awalan digunakan untuk pemetaan namespace XAML khas intrinsik bahasa XAML, dalam elemen akar file atau produksi XAML. Misalnya, templat Visual Studio untuk aplikasi WPF memulai file XAML menggunakan pemetaan ini x: . Anda dapat memilih token awalan yang berbeda dalam pemetaan namespace XAML Anda sendiri, tetapi dokumentasi ini akan mengasumsikan pemetaan default x: sebagai sarana untuk mengidentifikasi entitas yang merupakan bagian yang ditentukan dari namespace XAML untuk bahasa XAML, dibandingkan dengan namespace layanan default WPF atau namespace XAML lainnya yang tidak terkait dengan kerangka kerja tertentu.

Ekstensi Markup Khusus WPF

Ekstensi markup paling umum yang digunakan dalam pemrograman WPF adalah ekstensi yang mendukung referensi sumber daya (StaticResource dan DynamicResource), dan yang mendukung pengikatan data (Binding).

  • StaticResource menyediakan nilai untuk properti dengan mengganti nilai sumber daya yang sudah ditentukan. StaticResource Evaluasi pada akhirnya dibuat pada waktu pemuatan XAML dan tidak memiliki akses ke grafik objek pada waktu proses. Untuk detailnya, lihat Ekstensi Markup StaticResource.

  • DynamicResource memberikan nilai untuk properti dengan menugasi nilai tersebut menjadi referensi run-time ke sumber daya. Referensi sumber daya dinamis memaksa pencarian baru setiap kali sumber daya tersebut diakses dan memiliki akses ke grafik objek pada waktu proses. Untuk mendapatkan akses ini, DynamicResource konsep didukung oleh properti dependensi dalam sistem properti WPF, dan ekspresi yang dievaluasi. Oleh karena itu Anda hanya dapat menggunakan DynamicResource untuk target properti dependensi. Untuk detailnya, lihat Ekstensi Markup DynamicResource.

  • Binding menyediakan nilai terikat data untuk properti, menggunakan konteks data yang berlaku untuk objek induk pada waktu proses. Ekstensi markup ini relatif kompleks, karena mengaktifkan sintaksis sebaris yang substansial untuk menentukan pengikatan data. Untuk detailnya, lihat Mengikat Ekstensi Markup.

  • RelativeSource menyediakan informasi sumber untuk yang Binding dapat menavigasi beberapa kemungkinan hubungan di pohon objek run-time. Ini menyediakan sumber khusus untuk pengikatan yang dibuat dalam templat multi-penggunaan atau dibuat dalam kode tanpa pengetahuan penuh tentang pohon objek di sekitarnya. Untuk detailnya, lihat RelativeSource MarkupExtension.

  • TemplateBinding memungkinkan templat kontrol untuk menggunakan nilai untuk properti templat yang berasal dari properti kelas yang ditentukan model objek yang akan menggunakan templat. Dengan kata lain, properti dalam definisi templat dapat mengakses konteks yang hanya ada setelah templat diterapkan. Untuk detailnya, lihat TemplateBinding Markup Extension. Untuk informasi selengkapnya tentang penggunaan TemplateBindingpraktis , lihat Menata dengan Sampel ControlTemplates.

  • ColorConvertedBitmap mendukung skenario pencitraan yang relatif canggih. Untuk detailnya, lihat ColorConvertedBitmap Markup Extension.

  • ComponentResourceKey dan ThemeDictionary mendukung aspek pencarian sumber daya, terutama untuk sumber daya dan tema yang dikemas dengan kontrol kustom. Untuk informasi selengkapnya, lihat Ekstensi Markup ComponentResourceKey, Ekstensi Markup TemaDiksi, atau Gambaran Umum Penulisan Kontrol.

*Kelas Ekstensi

Untuk bahasa XAML umum dan ekstensi markup khusus WPF, perilaku setiap ekstensi markup diidentifikasi ke prosesor XAML melalui *Extension kelas yang berasal dari MarkupExtension, dan menyediakan implementasi ProvideValue metode . Metode ini pada setiap ekstensi menyediakan objek yang dikembalikan ketika ekstensi markup dievaluasi. Objek yang dikembalikan biasanya dievaluasi berdasarkan berbagai token string yang diteruskan ke ekstensi markup.

Misalnya, StaticResourceExtension kelas menyediakan implementasi permukaan pencarian sumber daya aktual sehingga implementasinya ProvideValue mengembalikan objek yang diminta, dengan input implementasi tertentu tersebut menjadi string yang digunakan untuk mencari sumber daya dengan x:Key. Sebagian besar detail implementasi ini tidak penting jika Anda menggunakan ekstensi markup yang ada.

Beberapa ekstensi markup tidak menggunakan argumen token string. Ini baik karena mereka mengembalikan nilai statis atau konsisten, atau karena konteks untuk nilai apa yang harus dikembalikan tersedia melalui salah satu layanan yang diteruskan melalui serviceProvider parameter .

Pola *Extension penamaan adalah untuk kenyamanan dan konsistensi. Prosesor XAML tidak diperlukan untuk mengidentifikasi kelas tersebut sebagai dukungan untuk ekstensi markup. Selama basis kode Anda mencakup System.Xaml dan menggunakan implementasi Layanan XAML .NET Framework, semua yang perlu dikenali sebagai ekstensi markup XAML adalah berasal dari MarkupExtension dan untuk mendukung sintaks konstruksi. WPF mendefinisikan kelas yang mengaktifkan ekstensi markup yang tidak mengikuti *Extension pola penamaan, misalnya Binding. Biasanya alasan untuk ini adalah bahwa kelas mendukung skenario di luar dukungan ekstensi markup murni. Dalam kasus Binding, kelas tersebut mendukung akses run-time ke metode dan properti objek untuk skenario yang tidak ada hubungannya dengan XAML.

Interpretasi Kelas Ekstensi Teks Inisialisasi

Token string yang mengikuti nama ekstensi markup dan masih dalam kurung kurawal ditafsirkan oleh prosesor XAML dengan salah satu cara berikut:

  • Koma selalu mewakili pemisah atau pemisah token individual.

  • Jika token yang dipisahkan individu tidak berisi tanda sama dengan, setiap token diperlakukan sebagai argumen konstruktor. Setiap parameter konstruktor harus diberikan seperti jenis yang diharapkan oleh tanda tangan tersebut, dan dalam urutan yang tepat yang diharapkan oleh tanda tangan tersebut.

    Catatan

    Prosesor XAML harus memanggil konstruktor yang cocok dengan jumlah argumen jumlah pasangan. Untuk alasan ini, jika Anda menerapkan ekstensi markup kustom, jangan berikan beberapa konstruktor dengan jumlah argumen yang sama. Perilaku tentang bagaimana prosesor XAML berperilaku jika lebih dari satu jalur konstruktor ekstensi markup dengan jumlah parameter yang sama tidak ditentukan, tetapi Anda harus mengantisipasi bahwa prosesor XAML diizinkan untuk melempar pengecualian pada penggunaan jika situasi ini ada dalam definisi jenis ekstensi markup.

  • Jika token yang dipisahkan individu berisi tanda yang sama, prosesor XAML terlebih dahulu memanggil konstruktor tanpa parameter untuk ekstensi markup. Kemudian, setiap pasangan nama=nilai ditafsirkan sebagai nama properti yang ada pada ekstensi markup, dan nilai untuk ditetapkan ke properti tersebut.

  • Jika ada hasil paralel antara perilaku konstruktor dan perilaku pengaturan properti dalam ekstensi markup, tidak masalah perilaku mana yang Anda gunakan. Penggunaan yang lebih umum untuk menggunakan pasangan nilai properti=untuk ekstensi markup yang memiliki lebih dari satu properti yang dapat diatur, jika hanya karena membuat markup Anda lebih disengaja dan Anda cenderung tidak sengaja mengubah urutan parameter konstruktor. (Saat Anda menentukan pasangan properti=nilai, properti tersebut mungkin dalam urutan apa pun.) Selain itu, tidak ada jaminan bahwa ekstensi markup memasok parameter konstruktor yang mengatur setiap properti yang dapat diatur. Misalnya, Binding adalah ekstensi markup, dengan banyak properti yang dapat diatur melalui ekstensi dalam bentuk nilai properti=, tetapi Binding hanya mendukung dua konstruktor: konstruktor tanpa parameter, dan yang mengatur jalur awal.

  • Koma harfiah tidak dapat diteruskan ke ekstensi markup tanpa escapement.

Urutan Escape dan Ekstensi Markup

Penanganan atribut dalam prosesor XAML menggunakan kurung kurawal sebagai indikator urutan ekstensi markup. Dimungkinkan juga untuk menghasilkan nilai atribut karakter kurung kurawal harfiah jika perlu, dengan memasukkan urutan escape menggunakan pasangan kurung kurawal kosong diikuti oleh kurung kurawal harfiah. Lihat {} Urutan Escape - Ekstensi Markup.

Ekstensi Markup Berlapis dalam Penggunaan XAML

Berlapisnya beberapa ekstensi markup didukung, dan setiap ekstensi markup akan dievaluasi paling dalam terlebih dahulu. Misalnya, pertimbangkan penggunaan berikut:

<Setter Property="Background"  
  Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />  

Dalam penggunaan ini, x:Static pernyataan dievaluasi terlebih dahulu dan mengembalikan string. String tersebut kemudian digunakan sebagai argumen untuk DynamicResource.

Ekstensi Markup dan Sintaks Elemen Properti

Saat digunakan sebagai elemen objek yang mengisi nilai elemen properti, kelas ekstensi markup secara visual tidak dapat dibedakan dari elemen objek yang didukung jenis umum yang dapat digunakan dalam XAML. Perbedaan praktis antara elemen objek umum dan ekstensi markup adalah bahwa ekstensi markup dievaluasi ke nilai yang ditik atau ditangguhkan sebagai ekspresi. Oleh karena itu mekanisme untuk setiap kemungkinan kesalahan jenis nilai properti untuk ekstensi markup akan berbeda, mirip dengan bagaimana properti terikat terlambat diperlakukan dalam model pemrograman lainnya. Elemen objek biasa akan dievaluasi untuk pencocokan jenis terhadap properti target yang diatur saat XAML diurai.

Sebagian besar ekstensi markup, ketika digunakan dalam sintaks elemen objek untuk mengisi elemen properti, tidak akan memiliki konten atau sintaks elemen properti lebih lanjut di dalamnya. Dengan demikian Anda akan menutup tag elemen objek, dan tidak menyediakan elemen turunan. Setiap kali ada elemen objek yang ditemui oleh prosesor XAML, konstruktor untuk kelas tersebut dipanggil, yang membuat instans objek yang dibuat dari elemen yang diurai. Kelas ekstensi markup tidak berbeda: jika Anda ingin ekstensi markup Anda dapat digunakan dalam sintaks elemen objek, Anda harus menyediakan konstruktor tanpa parameter. Beberapa ekstensi markup yang ada memiliki setidaknya satu nilai properti yang diperlukan yang harus ditentukan untuk inisialisasi yang efektif. Jika demikian, nilai properti tersebut biasanya diberikan sebagai atribut properti pada elemen objek. Di halaman referensi XAML Namespace (x:) Language Features dan WPF XAML Extensions, ekstensi markup yang memiliki properti yang diperlukan (dan nama properti yang diperlukan) akan dicatat. Halaman referensi juga akan mencatat apakah sintaks elemen objek atau sintaks atribut tidak diizinkan untuk ekstensi markup tertentu. Kasus penting adalah x:Array Markup Extension, yang tidak dapat mendukung sintaks atribut karena konten array tersebut harus ditentukan dalam penandaan sebagai konten. Konten array ditangani sebagai objek umum, oleh karena itu tidak ada pengonversi jenis default untuk atribut yang layak. Selain itu, x:Array Markup Extension memerlukan type parameter.

Baca juga