Detail Sintaksis XAML
Topik ini mendefinisikan istilah yang digunakan untuk menggambarkan elemen sintaks XAML. Istilah-istilah ini sering digunakan di seluruh sisa dokumentasi ini, baik untuk dokumentasi WPF secara khusus maupun untuk kerangka kerja lain yang menggunakan XAML atau konsep XAML dasar yang diaktifkan oleh dukungan bahasa XAML di tingkat System.Xaml. Topik ini memperluas terminologi dasar yang diperkenalkan dalam topik XAML di WPF.
Spesifikasi Bahasa XAML
Terminologi sintaks XAML yang ditentukan di sini juga ditentukan atau dirujuk dalam spesifikasi bahasa XAML. XAML adalah bahasa berdasarkan XML dan mengikuti atau memperluas aturan struktural XML. Beberapa terminologi dibagikan dari atau didasarkan pada terminologi yang umum digunakan saat menjelaskan bahasa XML atau model objek dokumen XML.
Untuk informasi selengkapnya tentang spesifikasi bahasa XAML, unduh [MS-XAML] dari Pusat Unduhan Microsoft.
XAML dan CLR
XAML adalah bahasa markup. Runtime bahasa umum (CLR), seperti yang disiratkan oleh namanya, memungkinkan eksekusi runtime. XAML bukan dengan sendirinya salah satu bahasa umum yang langsung dikonsumsi oleh runtime CLR. Sebagai gantinya, Anda dapat menganggap XAML sebagai pendukung sistem jenisnya sendiri. Sistem penguraian XAML tertentu yang digunakan oleh WPF dibangun pada CLR dan sistem jenis CLR. Jenis XAML dipetakan ke jenis CLR untuk membuat instans representasi run time saat XAML untuk WPF diurai. Untuk alasan ini, sisa diskusi sintaksis dalam dokumen ini akan mencakup referensi ke sistem jenis CLR, meskipun diskusi sintaksis yang setara dalam spesifikasi bahasa XAML tidak. (Sesuai tingkat spesifikasi bahasa XAML, jenis XAML dapat dipetakan ke sistem jenis lain, yang tidak harus CLR, tetapi itu akan memerlukan pembuatan dan penggunaan parser XAML yang berbeda.)
Anggota Jenis dan Warisan Kelas
Properti dan peristiwa saat muncul sebagai anggota XAML dari jenis WPF sering diwarisi dari jenis dasar. Misalnya, pertimbangkan contoh ini: <Button Background="Blue" .../>
. Properti Background bukan properti yang segera dideklarasikan pada Button kelas, jika Anda melihat definisi kelas, hasil pantulan, atau dokumentasi. Sebaliknya, Background diwarisi dari kelas dasar Control .
Perilaku pewarisan kelas elemen WPF XAML adalah kepergian yang signifikan dari interpretasi markup XML yang diberlakukan skema. Warisan kelas dapat menjadi kompleks, terutama ketika kelas dasar perantara abstrak, atau ketika antarmuka terlibat. Ini adalah salah satu alasan bahwa set elemen XAML dan atribut yang diizinkan sulit untuk mewakili secara akurat dan sepenuhnya menggunakan jenis skema yang biasanya digunakan untuk pemrograman XML, seperti format DTD atau XSD. Alasan lain adalah bahwa fitur ekstensibilitas dan pemetaan jenis bahasa XAML itu sendiri menghalangi kelengkapan representasi tetap dari jenis dan anggota yang diizinkan.
Sintaks Elemen Objek
Sintaks elemen objek adalah sintaks markup XAML yang membuat instans kelas atau struktur CLR dengan mendeklarasikan elemen XML. Sintaks ini menyerupan sintaks elemen dari bahasa markup lain seperti HTML. Sintaks elemen objek dimulai dengan tanda kurung sudut kiri (<), diikuti segera dengan nama jenis kelas atau struktur yang sedang dibuat. Nol atau lebih spasi dapat mengikuti nama jenis, dan nol atau lebih atribut juga dapat dideklarasikan pada elemen objek, dengan satu atau beberapa spasi yang memisahkan setiap pasangan nama atribut="nilai". Akhirnya, salah satu hal berikut ini harus benar:
Elemen dan tag harus ditutup dengan garis miring ke depan (/) diikuti segera oleh tanda kurung sudut kanan (>).
Tag pembuka harus diselesaikan dengan tanda kurung sudut kanan (>). Elemen objek lainnya, elemen properti, atau teks dalam, dapat mengikuti tag pembuka. Konten apa yang mungkin terkandung di sini biasanya dibatasi oleh model objek elemen. Tag penutup yang setara untuk elemen objek juga harus ada, dalam sarang dan keseimbangan yang tepat dengan pasangan tag pembuka dan penutup lainnya.
XAML seperti yang diimplementasikan oleh .NET memiliki sekumpulan aturan yang memetakan elemen objek ke dalam jenis, atribut ke dalam properti atau peristiwa, dan namespace XAML ke namespace CLR ditambah assembly. Untuk WPF dan .NET, elemen objek XAML dipetakan ke jenis .NET seperti yang didefinisikan dalam rakitan yang dirujuk, dan atribut memetakan ke anggota jenis tersebut. Saat Mereferensikan jenis CLR di XAML, Anda juga memiliki akses ke anggota yang diwariskan dari jenis tersebut.
Misalnya, contoh berikut adalah sintaks elemen objek yang membuat instans Name baru kelas, dan juga menentukan atribut dan nilai untuk atribut tersebutButton:
<Button Name="CheckoutButton"/>
Contoh berikut adalah sintaks elemen objek yang juga menyertakan sintaks properti konten XAML. Teks dalam yang terkandung dalam akan digunakan untuk mengatur TextBox properti konten XAML, Text.
<TextBox>This is a Text Box</TextBox>
Model Konten
Kelas mungkin mendukung penggunaan sebagai elemen objek XAML dalam hal sintaks, tetapi elemen tersebut hanya akan berfungsi dengan baik dalam aplikasi atau halaman ketika ditempatkan dalam posisi yang diharapkan dari con keseluruhan mode tenda l atau pohon elemen. Misalnya, MenuItem biasanya hanya boleh ditempatkan sebagai anak dari kelas turunan MenuBase seperti Menu. Con mode tenda ls untuk elemen tertentu didokumentasikan sebagai bagian dari komentar pada halaman kelas untuk kontrol dan kelas WPF lainnya yang dapat digunakan sebagai elemen XAML.
Properti Elemen Objek
Properti di XAML diatur oleh berbagai sintaks yang mungkin. Sintaks mana yang dapat digunakan untuk properti tertentu akan bervariasi, berdasarkan karakteristik sistem jenis yang mendasar dari properti yang Anda atur.
Dengan mengatur nilai properti, Anda menambahkan fitur atau karakteristik ke objek seperti yang ada di grafik objek run time. Status awal objek yang dibuat dari elemen objek didasarkan pada perilaku konstruktor tanpa parameter. Biasanya, aplikasi Anda akan menggunakan sesuatu selain instans default sepenuhnya dari objek tertentu.
Sintaks Atribut (Properti)
Sintaks atribut adalah sintaks markup XAML yang mengatur nilai untuk properti dengan mendeklarasikan atribut pada elemen objek yang ada. Nama atribut harus cocok dengan nama anggota CLR dari properti kelas yang mendukung elemen objek yang relevan. Nama atribut diikuti oleh operator penugasan (=). Nilai atribut harus berupa string yang diapit dalam tanda kutip.
Catatan
Anda dapat menggunakan tanda kutip alternatif untuk menempatkan tanda kutip harfiah dalam atribut. Misalnya Anda dapat menggunakan tanda kutip tunggal sebagai sarana untuk mendeklarasikan string yang berisi karakter kutipan ganda di dalamnya. Baik Anda menggunakan tanda kutip tunggal atau ganda, Anda harus menggunakan pasangan yang cocok untuk membuka dan menutup string nilai atribut. Ada juga urutan escape atau teknik lain yang tersedia untuk mengatasi pembatasan karakter yang diberlakukan oleh sintaks XAML tertentu. Lihat Entitas Karakter XML dan XAML.
Agar dapat diatur melalui sintaks atribut, properti harus publik dan harus dapat ditulis. Nilai properti dalam sistem jenis backing harus merupakan jenis nilai, atau harus merupakan jenis referensi yang dapat diinstansiasi atau dirujuk oleh prosesor XAML saat mengakses jenis backing yang relevan.
Untuk peristiwa WPF XAML, peristiwa yang direferensikan sebagai nama atribut harus bersifat publik dan memiliki delegasi publik.
Properti atau peristiwa harus menjadi anggota kelas atau struktur yang dibuat oleh elemen objek yang berisi.
Pemrosesan Nilai Atribut
Nilai string yang terkandung dalam tanda kutip pembuka dan penutupan diproses oleh prosesor XAML. Untuk properti, perilaku pemrosesan default ditentukan oleh jenis properti CLR yang mendasar.
Nilai atribut diisi oleh salah satu hal berikut, menggunakan urutan pemrosesan ini:
Jika prosesor XAML menemukan kurung kurawal, atau elemen objek yang berasal dari MarkupExtension, maka ekstensi markup yang direferensikan dievaluasi terlebih dahulu daripada memproses nilai sebagai string, dan objek yang dikembalikan oleh ekstensi markup digunakan sebagai nilai. Dalam banyak kasus, objek yang dikembalikan oleh ekstensi markup akan menjadi referensi ke objek yang ada, atau ekspresi yang menuguhkan evaluasi hingga durasi, dan bukan objek yang baru dibuat.
Jika properti dideklarasikan dengan atribut TypeConverter, atau jenis nilai properti tersebut dinyatakan dengan atribut TypeConverter, nilai string atribut dikirimkan ke pengonversi jenis sebagai input konversi, dan pengonversi akan mengembalikan instans objek baru.
Jika tidak TypeConverterada , konversi langsung ke jenis properti dicoba. Tingkat akhir ini adalah konversi langsung pada nilai parser-native antara jenis primitif bahasa XAML, atau pemeriksaan nama konstanta bernama dalam enumerasi (pengurai kemudian mengakses nilai yang cocok).
Nilai Atribut Enumerasi
Enumerasi dalam XAML diproses secara intrinsik oleh pengurai XAML, dan anggota enumerasi harus ditentukan dengan menentukan nama string dari salah satu konstanta bernama enumerasi.
Untuk nilai enumerasi nonflag, perilaku aslinya adalah memproses string nilai atribut dan menyelesaikannya ke salah satu nilai enumerasi. Anda tidak menentukan enumerasi dalam format Enumerasi.Nilai, seperti yang Anda lakukan dalam kode. Sebagai gantinya, Anda hanya menentukan Nilai, dan Enumerasi disimpulkan oleh jenis properti yang Anda atur. Jika Anda menentukan atribut dalam Enumerasi.Formulir nilai , tidak akan diselesaikan dengan benar.
Untuk enumerasi bertanda bendera, perilaku didasarkan pada Enum.Parse metode . Anda dapat menentukan beberapa nilai untuk enumerasi berbendera dengan memisahkan setiap nilai dengan koma. Namun, Anda tidak dapat menggabungkan nilai enumerasi yang tidak berbendera. Misalnya, Anda tidak dapat menggunakan sintaks koma untuk mencoba membuat Trigger yang bertindak pada beberapa kondisi enumerasi nonflag:
<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
<Setter ... />
</Trigger>
...
Enumerasi flagwise yang mendukung atribut yang dapat diatur di XAML jarang terjadi di WPF. Namun, salah satu enumerasi tersebut adalah StyleSimulations. Anda dapat, misalnya, menggunakan sintaks atribut flagwise yang dibatasi koma untuk memodifikasi contoh yang disediakan dalam Komentar untuk Glyphs kelas; StyleSimulations = "BoldSimulation"
bisa menjadi StyleSimulations = "BoldSimulation,ItalicSimulation"
. KeyBinding.Modifiers adalah properti lain di mana lebih dari satu nilai enumerasi dapat ditentukan. Namun, properti ini kebetulan merupakan kasus khusus, karena ModifierKeys enumerasi mendukung pengonversi jenisnya sendiri. Pengonversi jenis untuk pengubah menggunakan tanda plus (+) sebagai pemisah daripada koma (,). Konversi ini mendukung sintaksis yang lebih tradisional untuk mewakili kombinasi kunci dalam pemrograman Microsoft Windows, seperti "Ctrl+Alt".
Properti dan Referensi Nama Anggota Peristiwa
Saat menentukan atribut, Anda dapat mereferensikan properti atau peristiwa apa pun yang ada sebagai anggota jenis CLR yang Anda buat untuk elemen objek yang berisi.
Atau, Anda dapat mereferensikan properti terlampir atau peristiwa terlampir, terlepas dari elemen objek yang berisi. (Properti terlampir dibahas di bagian yang akan datang.)
Anda juga dapat memberi nama peristiwa apa pun dari objek apa pun yang dapat diakses melalui namespace default dengan menggunakan typeName.nama peristiwa yang memenuhi syarat sebagian; sintaks ini mendukung melampirkan handler untuk peristiwa yang dirutekan di mana handler dimaksudkan untuk menangani perutean peristiwa dari elemen turunan, tetapi elemen induk tidak juga memiliki peristiwa tersebut dalam tabel anggotanya. Sintaks ini menyerupan sintaks peristiwa terlampir, tetapi peristiwa di sini bukan kejadian terlampir benar. Sebagai gantinya, Anda merujuk peristiwa dengan nama yang memenuhi syarat. Untuk informasi lebih lanjut, lihat Gambaran Umum Peristiwa yang Dirutekan.
Untuk beberapa skenario, nama properti terkadang disediakan sebagai nilai atribut, bukan nama atribut. Nama properti tersebut juga dapat menyertakan kualifikasi, seperti properti yang ditentukan dalam form ownerType.dependencyPropertyName. Skenario ini umum saat menulis gaya atau templat di XAML. Aturan pemrosesan untuk nama properti yang disediakan sebagai nilai atribut berbeda, dan diatur oleh jenis properti yang ditetapkan atau oleh perilaku subsistem WPF tertentu. Untuk detailnya, lihat Gaya dan Templat.
Penggunaan lain untuk nama properti adalah ketika nilai atribut menjelaskan hubungan properti-properti. Fitur ini digunakan untuk pengikatan data dan untuk target papan cerita, dan diaktifkan oleh PropertyPath kelas dan pengonversi jenisnya. Untuk deskripsi yang lebih lengkap tentang semantik pencarian, lihat Sintaks PropertyPath XAML.
Sintaks Elemen Properti
Sintaks elemen properti adalah sintaksis yang agak berbeda dari aturan sintaks XML dasar untuk elemen. Dalam XML, nilai atribut adalah string de facto, dengan satu-satunya kemungkinan variasi adalah format pengodean string mana yang digunakan. Di XAML, Anda dapat menetapkan elemen objek lain untuk menjadi nilai properti. Kemampuan ini diaktifkan oleh sintaks elemen properti. Alih-alih properti yang ditentukan sebagai atribut dalam tag elemen, properti ditentukan menggunakan tag elemen pembuka di elemenTypeName.formulir propertyName , nilai properti ditentukan di dalam, lalu elemen properti ditutup.
Secara khusus, sintaks dimulai dengan kurung sudut kiri (<), diikuti segera dengan nama jenis kelas atau struktur yang dimuat sintaks elemen properti. Ini diikuti dengan satu titik (.), kemudian dengan nama properti, kemudian dengan tanda kurung sudut kanan (>). Seperti sintaks atribut, properti tersebut harus ada dalam anggota publik yang dideklarasikan dari jenis yang ditentukan. Nilai yang akan ditetapkan ke properti terkandung dalam elemen properti. Biasanya, nilai diberikan sebagai satu atau beberapa elemen objek, karena menentukan objek sebagai nilai adalah skenario yang dimaksudkan sintaks elemen properti untuk ditangani. Terakhir, tag penutup yang setara yang menentukan elementTypeName yang sama.kombinasi propertyName harus disediakan, dalam sarang dan keseimbangan yang tepat dengan tag elemen lainnya.
Misalnya, berikut ini adalah sintaks elemen properti untuk ContextMenu properti dari Button.
<Button>
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="1">First item</MenuItem>
<MenuItem Header="2">Second item</MenuItem>
</ContextMenu>
</Button.ContextMenu>
Right-click me!</Button>
Nilai dalam elemen properti juga dapat diberikan sebagai teks dalam, dalam kasus di mana jenis properti yang ditentukan adalah jenis nilai primitif, seperti String, atau enumerasi tempat nama ditentukan. Kedua penggunaan ini agak jarang terjadi, karena masing-masing kasus ini juga dapat menggunakan sintaks atribut yang lebih sederhana. Salah satu skenario untuk mengisi elemen properti dengan string adalah untuk properti yang bukan properti konten XAML tetapi masih digunakan untuk representasi teks UI, dan elemen spasi putih tertentu seperti linefeed diperlukan untuk muncul dalam teks UI tersebut. Sintaks atribut tidak dapat mempertahankan linefeed, tetapi sintaks elemen properti dapat, selama pelestarian spasi putih yang signifikan aktif (untuk detailnya, lihat Pemrosesan spasi kosong di XAML). Skenario lain adalah agar x:Uid Directive dapat diterapkan ke elemen properti dan dengan demikian menandai nilai dalam sebagai nilai yang harus dilokalkan dalam BAML output WPF atau dengan teknik lain.
Elemen properti tidak diwakili di pohon logis WPF. Elemen properti hanyalah sintaksis tertentu untuk mengatur properti, dan bukan elemen yang memiliki instans atau objek yang mendukungnya. (Untuk detail tentang konsep pohon logis, lihat Pohon di WPF.)
Untuk properti di mana sintaks atribut dan elemen properti didukung, dua sintaks umumnya memiliki hasil yang sama, meskipun seluk beluk seperti penanganan spasi putih dapat sedikit bervariasi di antara sintaks.
Sintaks Koleksi
Spesifikasi XAML memerlukan implementasi prosesor XAML untuk mengidentifikasi properti di mana jenis nilai adalah koleksi. Implementasi prosesor XAML umum di .NET didasarkan pada kode terkelola dan CLR, dan mengidentifikasi jenis koleksi melalui salah satu hal berikut:
Jenis mengimplementasikan IList.
Jenis mengimplementasikan IDictionary.
Jenis berasal dari Array (untuk informasi selengkapnya tentang array di XAML, lihat x:Array Markup Extension.)
Jika jenis properti adalah koleksi, maka jenis koleksi yang disimpulkan tidak perlu ditentukan dalam markup sebagai elemen objek. Sebagai gantinya, elemen yang dimaksudkan untuk menjadi item dalam koleksi ditentukan sebagai satu atau beberapa elemen turunan dari elemen properti. Setiap item tersebut dievaluasi ke objek selama pemuatan dan ditambahkan ke koleksi dengan memanggil Add
metode pengumpulan tersirat. Misalnya, Triggers properti mengambil Style jenis TriggerCollectionkoleksi khusus , yang mengimplementasikan IList. Tidak perlu membuat instans TriggerCollection elemen objek dalam markup. Sebagai gantinya, Anda menentukan satu atau beberapa Trigger item sebagai elemen dalam Style.Triggers
elemen properti, di mana Trigger (atau kelas turunan) adalah jenis yang diharapkan sebagai jenis item untuk jenis yang sangat di ketik dan implisit TriggerCollection.
<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="true">
<Setter Property = "Background" Value="Red"/>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Setter Property = "Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
Properti mungkin merupakan jenis koleksi dan properti konten XAML untuk jenis tersebut dan jenis turunan, yang dibahas di bagian berikutnya dari topik ini.
Elemen koleksi implisit membuat anggota di representasi pohon logis, meskipun tidak muncul di markup sebagai elemen. Biasanya konstruktor jenis induk melakukan instansiasi untuk koleksi yang merupakan salah satu propertinya, dan koleksi yang awalnya kosong menjadi bagian dari pohon objek.
Catatan
Daftar generik dan antarmuka kamus (IList<T> dan IDictionary<TKey,TValue>) tidak didukung untuk deteksi koleksi. Namun, Anda dapat menggunakan List<T> kelas sebagai kelas dasar, karena mengimplementasikan IList secara langsung, atau Dictionary<TKey,TValue> sebagai kelas dasar, karena menerapkannya IDictionary secara langsung.
Di halaman Referensi .NET untuk jenis koleksi, sintaksis ini dengan kelalaian sengaja dari elemen objek untuk koleksi terkadang dicatat di bagian sintaks XAML sebagai Sintaks Koleksi Implisit.
Dengan pengecualian elemen akar, setiap elemen objek dalam file XAML yang disarangkan sebagai elemen turunan dari elemen lain benar-benar merupakan elemen yang merupakan salah satu atau kedua kasus berikut: anggota properti koleksi implisit dari elemen induknya, atau elemen yang menentukan nilai properti konten XAML untuk elemen induk (properti konten XAML akan dibahas di bagian yang akan datang). Dengan kata lain, hubungan elemen induk dan elemen turunan di halaman markup benar-benar merupakan objek tunggal di akar, dan setiap elemen objek di bawah akar adalah instans tunggal yang menyediakan nilai properti induk, atau salah satu item dalam koleksi yang juga merupakan nilai properti jenis koleksi induk. Konsep akar tunggal ini umum dengan XML, dan sering diperkuat dalam perilaku API yang memuat XAML seperti Load.
Contoh berikut adalah sintaksis dengan elemen objek untuk koleksi (GradientStopCollection) yang ditentukan secara eksplisit.
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
Perhatikan bahwa tidak selalu mungkin untuk secara eksplisit mendeklarasikan koleksi. Misalnya, mencoba mendeklarasikan TriggerCollection secara eksplisit dalam contoh yang ditampilkan Triggers sebelumnya akan gagal. Secara eksplisit menyatakan koleksi mengharuskan kelas koleksi harus mendukung konstruktor tanpa parameter, dan TriggerCollection tidak memiliki konstruktor tanpa parameter.
Properti Konten XAML
Sintaks konten XAML adalah sintaks yang hanya diaktifkan pada kelas yang menentukan ContentPropertyAttribute sebagai bagian dari deklarasi kelasnya. Referensi nama properti yang merupakan properti konten untuk jenis elemen tersebut ContentPropertyAttribute (termasuk kelas turunan). Ketika diproses oleh prosesor XAML, elemen turunan atau teks dalam apa pun yang ditemukan antara tag pembuka dan penutup elemen objek akan ditetapkan menjadi nilai properti konten XAML untuk objek tersebut. Anda diizinkan untuk menentukan elemen properti eksplisit untuk properti konten, tetapi penggunaan ini umumnya tidak ditampilkan di bagian sintaks XAML dalam referensi .NET. Teknik eksplisit/verbose memiliki nilai sesekali untuk kejelasan markup atau sebagai masalah gaya markup, tetapi biasanya niat properti konten adalah untuk merampingkan markup sehingga elemen yang terkait secara intuitif sebagai induk-anak dapat disarangkan secara langsung. Tag elemen properti untuk properti lain pada elemen tidak ditetapkan sebagai "konten" per definisi bahasa XAML yang ketat; mereka diproses sebelumnya dalam urutan pemrosesan pengurai XAML dan tidak dianggap sebagai "konten".
Nilai properti konten XAML harus berdampingan
Nilai properti konten XAML harus diberikan sepenuhnya sebelum atau seluruhnya setelah elemen properti lain pada elemen objek tersebut. Ini benar apakah nilai properti konten XAML ditentukan sebagai string, atau sebagai satu atau beberapa objek. Misalnya, markup berikut tidak mengurai:
<Button>I am a
<Button.Background>Blue</Button.Background>
blue button</Button>
Ini ilegal pada dasarnya karena jika sintaks ini dibuat eksplisit dengan menggunakan sintaks elemen properti untuk properti konten, maka properti konten akan diatur dua kali:
<Button>
<Button.Content>I am a </Button.Content>
<Button.Background>Blue</Button.Background>
<Button.Content> blue button</Button.Content>
</Button>
Contoh ilegal yang sama adalah jika properti konten adalah koleksi, dan elemen turunan diselingi dengan elemen properti:
<StackPanel>
<Button>This example</Button>
<StackPanel.Resources>
<SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
</StackPanel.Resources>
<Button>... is illegal XAML</Button>
</StackPanel>
Properti Konten dan Sintaks Koleksi Digabungkan
Untuk menerima lebih dari satu elemen objek sebagai konten, jenis properti konten harus secara khusus menjadi jenis koleksi. Mirip dengan sintaks elemen properti untuk jenis koleksi, prosesor XAML harus mengidentifikasi jenis yang merupakan jenis koleksi. Jika elemen memiliki properti konten XAML dan jenis properti konten XAML adalah koleksi, maka jenis koleksi tersirat tidak perlu ditentukan dalam markup sebagai elemen objek dan properti konten XAML tidak perlu ditentukan sebagai elemen properti. Oleh karena itu, con mode tenda l yang jelas dalam markup sekarang dapat memiliki lebih dari satu elemen turunan yang ditetapkan sebagai konten. Berikut ini adalah sintaks konten untuk Panel kelas turunan. Semua Panel kelas turunan menetapkan properti konten XAML menjadi Children, yang memerlukan nilai jenis UIElementCollection.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</StackPanel>
</Page>
Perhatikan bahwa tidak ada elemen properti untuk Children atau elemen untuk UIElementCollection yang diperlukan dalam markup. Ini adalah fitur desain XAML sehingga elemen yang terkandung secara rekursif yang mendefinisikan UI lebih intuitif diwakili sebagai pohon elemen berlapis dengan hubungan elemen induk-turunan langsung, tanpa mengintervensi tag elemen properti atau objek koleksi. Bahkan, UIElementCollection tidak dapat ditentukan secara eksplisit dalam markup sebagai elemen objek, berdasarkan desain. Karena satu-satunya penggunaan yang dimaksudkan adalah sebagai koleksi implisit, UIElementCollection tidak mengekspos konstruktor tanpa parameter publik dan dengan demikian tidak dapat dibuat sebagai elemen objek.
Mencampur Elemen Properti dan Elemen Objek dalam Objek dengan Properti Konten
Spesifikasi XAML menyatakan bahwa prosesor XAML dapat memberlakukan bahwa elemen objek yang digunakan untuk mengisi properti konten XAML dalam elemen objek harus bersebelahan, dan tidak boleh dicampur. Pembatasan terhadap pencampuran elemen dan konten properti ini diberlakukan oleh prosesor WPF XAML.
Anda dapat memiliki elemen objek turunan sebagai markup langsung pertama dalam elemen objek. Kemudian Anda dapat memperkenalkan elemen properti. Atau, Anda dapat menentukan satu atau beberapa elemen properti, lalu konten, lalu lebih banyak elemen properti. Tetapi setelah elemen properti mengikuti konten, Anda tidak dapat memperkenalkan konten lebih lanjut, Anda hanya dapat menambahkan elemen properti.
Persyaratan urutan elemen konten/properti ini tidak berlaku untuk teks dalam yang digunakan sebagai konten. Namun, ini masih merupakan gaya markup yang baik untuk menjaga teks dalam tetap berdekatan, karena ruang putih yang signifikan akan sulit dideteksi secara visual dalam markup jika elemen properti diselingi dengan teks dalam.
Namespace XAML
Tidak ada contoh sintaks sebelumnya yang menentukan namespace XAML selain namespace XAML default. Dalam aplikasi WPF umum, namespace XAML default ditentukan untuk menjadi namespace layanan WPF. Anda dapat menentukan namespace XAML selain namespace XAML default dan masih menggunakan sintaks yang sama. Tetapi kemudian, di mana saja kelas diberi nama yang tidak dapat diakses dalam namespace XAML default, nama kelas tersebut harus didahului dengan awalan namespace XAML seperti yang dipetakan ke namespace CLR yang sesuai. Misalnya, <custom:Example/>
adalah sintaks elemen objek untuk membuat instans Example
kelas, di mana namespace CLR yang berisi kelas tersebut (dan mungkin informasi rakitan eksternal yang berisi jenis backing) sebelumnya dipetakan ke custom
awalan.
Untuk informasi selengkapnya tentang namespace XAML, lihat Namespace XAML dan Pemetaan Namespace layanan untuk WPF XAML.
Ekstensi Markup
XAML mendefinisikan entitas pemrograman ekstensi markup yang memungkinkan escape dari penanganan prosesor XAML normal dari nilai atribut string atau elemen objek, dan menugaskan pemrosesan ke kelas pendukung. Karakter yang mengidentifikasi ekstensi markup ke prosesor XAML saat menggunakan sintaks atribut adalah kurung kurawal pembuka ({), diikuti oleh karakter apa pun selain kurung kurawal penutup (}). String pertama yang mengikuti kurung kurawal pembuka harus mereferensikan kelas yang menyediakan perilaku ekstensi tertentu, di mana referensi dapat menghilangkan substring "Ekstensi" jika substring tersebut adalah bagian dari nama kelas yang sebenarnya. Setelah itu, satu ruang dapat muncul, dan kemudian setiap karakter yang berhasil digunakan sebagai input oleh implementasi ekstensi, hingga kurung kurawal penutup ditemui.
Implementasi .NET XAML menggunakan MarkupExtension kelas abstrak sebagai dasar untuk semua ekstensi markup yang didukung oleh WPF serta kerangka kerja atau teknologi lainnya. Ekstensi markup yang secara khusus diterapkan WPF sering dimaksudkan untuk memberikan sarana untuk mereferensikan objek lain yang ada, atau untuk membuat referensi yang ditangguhkan ke objek yang akan dievaluasi pada waktu proses. Misalnya, pengikatan data WPF sederhana dilakukan dengan menentukan {Binding}
ekstensi markup sebagai pengganti nilai yang biasanya akan diambil properti tertentu. Banyak ekstensi markup WPF mengaktifkan sintaks atribut untuk properti di mana sintaks atribut tidak akan dimungkinkan. Misalnya, Style objek adalah jenis yang relatif kompleks yang berisi serangkaian objek dan properti berlapis. Gaya dalam WPF biasanya didefinisikan sebagai sumber daya dalam , lalu dirujuk ResourceDictionarymelalui salah satu dari dua ekstensi markup WPF yang meminta sumber daya. Ekstensi markup menumpuk evaluasi nilai properti ke pencarian sumber daya dan memungkinkan penyediaan Style nilai properti, mengambil jenis Style, dalam sintaks atribut seperti dalam contoh berikut:
<Button Style="{StaticResource MyStyle}">My button</Button>
Di sini, StaticResource
mengidentifikasi kelas yang StaticResourceExtension menyediakan implementasi ekstensi markup. String MyStyle
berikutnya digunakan sebagai input untuk konstruktor non-default StaticResourceExtension , di mana parameter sebagai diambil dari string ekstensi mendeklarasikan yang diminta ResourceKey. MyStyle
diharapkan menjadi nilai x:Key dari yang Style didefinisikan sebagai sumber daya. Penggunaan Ekstensi Markup StaticResource meminta sumber daya digunakan untuk memberikan Style nilai properti melalui logika pencarian sumber daya statis pada waktu pemuatan.
Untuk informasi selengkapnya tentang ekstensi markup, lihat Ekstensi Markup dan WPF XAML. Untuk referensi ekstensi markup dan fitur pemrograman XAML lainnya yang diaktifkan dalam implementasi XAML .NET umum, lihat Fitur Bahasa XAML Namespace (x:). Untuk ekstensi markup khusus WPF, lihat Ekstensi WPF XAML.
Properti yang Terlampir
Properti terlampir adalah konsep pemrograman yang diperkenalkan dalam XAML di mana properti dapat dimiliki dan didefinisikan oleh jenis tertentu, tetapi ditetapkan sebagai atribut atau elemen properti pada elemen apa pun. Skenario utama yang ditujukan untuk properti terlampir adalah mengaktifkan elemen turunan dalam struktur markup untuk melaporkan informasi ke elemen induk tanpa memerlukan model objek yang dibagikan secara luas di semua elemen. Sebaliknya, properti terlampir dapat digunakan oleh elemen induk untuk melaporkan informasi ke elemen turunan. Untuk informasi selengkapnya tentang tujuan properti terlampir dan cara membuat properti terlampir Anda sendiri, lihat Gambaran Umum Properti Terlampir.
Properti terlampir menggunakan sintaksis yang secara dangkal menyerupan sintaks elemen properti, karena Anda juga menentukan typeName.kombinasi propertyName . Ada dua perbedaan penting:
Anda dapat menggunakan typeName.kombinasi propertyName bahkan saat mengatur properti terlampir melalui sintaks atribut. Properti terlampir adalah satu-satunya kasus di mana memenuhi syarat nama properti adalah persyaratan dalam sintaks atribut.
Anda juga dapat menggunakan sintaks elemen properti untuk properti terlampir. Namun, untuk sintaks elemen properti umum, typeName yang Anda tentukan adalah elemen objek yang berisi elemen properti. Jika Anda merujuk ke properti terlampir, maka typeName adalah kelas yang menentukan properti terlampir, bukan elemen objek yang berisi.
Acara yang Terlampir
Peristiwa terlampir adalah konsep pemrograman lain yang diperkenalkan di XAML di mana peristiwa dapat didefinisikan oleh jenis tertentu, tetapi handler dapat dilampirkan pada elemen objek apa pun. Dalam implementasi WOF, seringkali jenis yang mendefinisikan peristiwa terlampir adalah jenis statis yang mendefinisikan layanan, dan terkadang peristiwa terlampir tersebut diekspos oleh alias peristiwa yang dirutekan dalam jenis yang mengekspos layanan. Handler untuk peristiwa terlampir ditentukan melalui sintaks atribut. Seperti halnya peristiwa terlampir, sintaks atribut diperluas untuk peristiwa terlampir untuk mengizinkan typeName.penggunaan eventName , di mana typeName adalah kelas yang menyediakan Add
dan Remove
pengatur penanganan aktivitas untuk infrastruktur peristiwa yang dilampirkan, dan eventName adalah nama peristiwa.
Anatomi Elemen Akar XAML
Tabel berikut menunjukkan elemen akar XAML umum yang dipecah, memperlihatkan atribut tertentu dari elemen akar:
Atribut | Deskripsi |
---|---|
<Page |
Membuka elemen objek dari elemen akar |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
Namespace XAML default (WPF) |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
Namespace XAML bahasa XAML |
x:Class="ExampleNamespace.ExampleCode" |
Deklarasi kelas parsial yang menyambungkan markup ke kode apa pun yang didefinisikan untuk kelas parsial |
> |
Akhir elemen objek untuk akar. Objek belum ditutup karena elemen berisi elemen turunan |
Penggunaan XAML Opsional dan Tidak Terkorekommen
Bagian berikut menjelaskan penggunaan XAML yang secara teknis didukung oleh prosesor XAML, tetapi itu menghasilkan verbositas atau masalah estetika lainnya yang mengganggu file XAML yang tetap dapat dibaca manusia saat Anda mengembangkan aplikasi yang berisi sumber XAML.
Penggunaan Elemen Properti Opsional
Penggunaan elemen properti opsional termasuk menulis properti konten elemen secara eksplisit yang dianggap implisit oleh prosesor XAML. Misalnya, ketika Anda mendeklarasikan konten Menu, Anda dapat memilih untuk secara eksplisit mendeklarasikan Items koleksi Menu sebagai <Menu.Items>
tag elemen properti, dan menempatkan masing-masing MenuItem di dalam <Menu.Items>
, daripada menggunakan perilaku prosesor XAML implisit bahwa semua elemen Menu anak harus menjadi dan MenuItem ditempatkan dalam Items koleksi. Terkadang penggunaan opsional dapat membantu memperjelas struktur objek secara visual seperti yang diwakili dalam markup. Atau terkadang penggunaan elemen properti eksplisit dapat menghindari markup yang secara teknis berfungsi tetapi membingungkan secara visual, seperti ekstensi markup berlapis dalam nilai atribut.
Atribut Lengkap typeName.memberName Qualified
TypeName.formulir memberName untuk atribut sebenarnya berfungsi lebih universal daripada hanya kasus peristiwa yang dirutekan. Tetapi dalam situasi lain bentuk itu berlebihan dan Anda harus menghindarinya, jika hanya karena alasan gaya markup dan keterbacaan. Dalam contoh berikut, masing-masing dari tiga referensi ke Background atribut benar-benar setara:
<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>
Button.Background
berfungsi karena pencarian yang memenuhi syarat untuk properti Button tersebut berhasil (Background diwarisi dari Kontrol) dan Button merupakan kelas elemen objek atau kelas dasar. Control.Background
bekerja karena Control kelas benar-benar mendefinisikan Background dan Control merupakan Button kelas dasar.
Namun, typeName berikut.contoh formulir memberName tidak berfungsi dan dengan demikian ditampilkan dikomentari:
<!--<Button Label.Background="Blue">Does not work</Button> -->
Label adalah kelas turunan lain dari Control, dan jika Anda telah menentukan Label.Background
dalam Label elemen objek, penggunaan ini akan berfungsi. Namun, karena Label bukan kelas atau kelas Buttondasar , perilaku prosesor XAML yang ditentukan adalah untuk kemudian memproses Label.Background
sebagai properti terlampir. Label.Background
bukan properti terlampir yang tersedia, dan penggunaan ini gagal.
Elemen Properti baseTypeName.memberName
Dengan cara yang dianalogikan tentang cara typeName.formulir memberName berfungsi untuk sintaks atribut, baseTypeName.sintaks memberName berfungsi untuk sintaks elemen properti. Misalnya, sintaks berikut berfungsi:
<Button>Control.Background PE
<Control.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>
</Control.Background>
</Button>
Di sini, elemen properti diberikan seolah-olah Control.Background
elemen properti terkandung dalam Button
.
Tapi sama seperti typeName.formulir memberName untuk atribut, baseTypeName.memberName adalah gaya yang buruk dalam markup, dan Anda harus menghindarinya.
Baca juga
.NET Desktop feedback