Bagikan melalui


Tentukan jenis kustom untuk digunakan dengan Layanan .NET XAML

Saat Anda menentukan jenis kustom yang merupakan objek bisnis atau merupakan jenis yang tidak memiliki dependensi pada kerangka kerja tertentu, ada praktik terbaik tertentu untuk XAML yang dapat Anda ikuti. Jika Anda mengikuti praktik ini, Layanan XAML .NET dan pembaca XAML dan penulis XAML dapat menemukan karakteristik XAML jenis Anda dan memberikan representasi yang sesuai dalam aliran simpul XAML menggunakan sistem jenis XAML. Topik ini menjelaskan praktik terbaik untuk definisi jenis, definisi anggota, dan attributing CLR jenis atau anggota.

Pola Konstruktor dan Definisi Jenis untuk XAML

Untuk dibuat sebagai elemen objek di XAML, kelas kustom harus memenuhi persyaratan berikut:

  • Kelas kustom harus publik dan harus mengekspos konstruktor publik tanpa parameter. (Lihat bagian berikut untuk catatan mengenai struktur.)

  • Kelas kustom tidak boleh menjadi kelas berlapis. "Titik" tambahan di jalur nama lengkap membuat pembagian namespace kelas ambigu, dan mengganggu fitur XAML lainnya seperti properti terlampir. Jika objek dapat dibuat sebagai elemen objek, objek yang dibuat dapat mengisi bentuk elemen properti dari properti apa pun yang mengambil objek sebagai jenis yang mendasarnya.

Anda masih dapat menyediakan nilai objek untuk jenis yang tidak memenuhi kriteria ini, jika Anda mengaktifkan pengonversi nilai. Untuk informasi selengkapnya, lihat Jenis Pengonversi dan Ekstensi Markup untuk XAML.

Struktur

Struktur selalu dapat dibangun dalam XAML, menurut definisi CLR. Ini karena pengkompilasi CLR secara implisit membuat konstruktor tanpa parameter untuk struktur. Konstruktor ini menginisialisasi semua nilai properti ke defaultnya.

Dalam beberapa kasus, perilaku konstruksi default untuk struktur tidak diinginkan. Ini mungkin karena struktur dimaksudkan untuk mengisi nilai dan berfungsi secara konseptual sebagai serikat. Sebagai penyatuan, nilai yang terkandung mungkin memiliki interpretasi yang saling eksklusif, dan oleh karena itu, tidak ada propertinya yang dapat diatur. Contoh struktur seperti itu dalam kosakata WPF adalah GridLength. Struktur tersebut harus mengimplementasikan pengonversi jenis sehingga nilai dapat diekspresikan dalam bentuk atribut, dengan menggunakan konvensi string yang membuat interpretasi atau mode nilai struktur yang berbeda. Struktur juga harus mengekspos perilaku serupa untuk konstruksi kode melalui konstruktor non-parameterless.

Antarmuka

Antarmuka dapat digunakan sebagai jenis anggota yang mendasar. Sistem jenis XAML memeriksa daftar yang dapat ditetapkan dan mengharapkan bahwa objek yang disediakan sebagai nilai dapat ditetapkan ke antarmuka. Tidak ada konsep bagaimana antarmuka harus disajikan sebagai jenis XAML selama jenis yang dapat ditetapkan yang relevan mendukung persyaratan konstruksi XAML.

Metode Pabrik

Metode pabrik adalah fitur XAML 2009. Mereka memodifikasi prinsip XAML bahwa objek harus memiliki konstruktor tanpa parameter. Metode pabrik tidak didokumenkan dalam artikel ini. Lihat x:FactoryMethod Directive.

Enumerasi

Enumerasi memiliki perilaku konversi jenis asli XAML. Nama konstanta enumerasi yang ditentukan dalam XAML diselesaikan terhadap jenis enumerasi yang mendasar, dan mengembalikan nilai enumerasi ke penulis objek XAML.

XAML mendukung penggunaan gaya bendera untuk enumerasi dengan FlagsAttribute diterapkan. Untuk informasi selengkapnya, lihat Sintaks XAML Secara Rinci. (Sintaks XAML Secara Rinci ditulis untuk audiens WPF, tetapi sebagian besar informasi dalam topik tersebut relevan untuk XAML yang tidak spesifik untuk kerangka kerja penerapan tertentu.)

Definisi Anggota

Jenis dapat menentukan anggota untuk penggunaan XAML. Dimungkinkan bagi jenis untuk menentukan anggota yang dapat digunakan XAML meskipun jenis tertentu tersebut tidak dapat digunakan XAML. Hal ini dimungkinkan karena warisan CLR. Selama beberapa jenis yang mewarisi anggota mendukung penggunaan XAML sebagai jenis, dan anggota mendukung penggunaan XAML untuk jenis yang mendasar atau memiliki sintaks XAML asli yang tersedia, anggota tersebut dapat digunakan XAML.

Properti

Jika Anda menentukan properti sebagai properti CLR publik menggunakan pola CLR get dan set aksesor umum dan kata kunci yang sesuai bahasa, sistem jenis XAML dapat melaporkan properti sebagai anggota dengan informasi yang sesuai yang disediakan untuk XamlMember properti, seperti IsReadPublic dan IsWritePublic.

Properti tertentu dapat mengaktifkan sintaks teks dengan menerapkan TypeConverterAttribute. Untuk informasi selengkapnya, lihat Jenis Pengonversi dan Ekstensi Markup untuk XAML.

Dengan tidak adanya sintaks teks atau konversi XAML asli dan dengan tidak adanya tidak langsung lebih lanjut, seperti penggunaan ekstensi markup, jenis properti (TargetType dalam sistem jenis XAML) harus dapat mengembalikan instans ke penulis objek XAML dengan memperlakukan jenis target sebagai jenis CLR.

Jika menggunakan XAML 2009, x:Reference Markup Extension dapat digunakan untuk memberikan nilai jika pertimbangan sebelumnya tidak terpenuhi; namun, itu lebih merupakan masalah penggunaan daripada masalah definisi jenis.

Aktivitas

Jika Anda menentukan peristiwa sebagai peristiwa CLR publik, sistem jenis XAML dapat melaporkan peristiwa sebagai anggota dengan IsEvent sebagai true. Pengabelan penanganan aktivitas tidak berada dalam cakupan kemampuan Layanan XAML .NET; kabel diserahkan ke kerangka kerja dan implementasi tertentu.

Metode

Kode sebaris untuk metode bukanlah kemampuan XAML default. Dalam kebanyakan kasus, Anda tidak secara langsung mereferensikan anggota metode dari XAML, dan peran metode dalam XAML hanya untuk memberikan dukungan untuk pola XAML tertentu. x:FactoryMethod Directive adalah pengecualian.

Bidang

Pedoman desain CLR mencegah bidang nonstatis. Untuk bidang statis, Anda hanya dapat mengakses nilai bidang statis melalui x:Static Markup Extension; dalam hal ini Anda tidak melakukan sesuatu yang istimewa dalam definisi CLR untuk mengekspos bidang untuk penggunaan x:Statis .

Anggota yang Dapat Dilampirkan

Anggota yang dapat dilampirkan diekspos ke XAML melalui pola metode aksesor pada jenis yang menentukan. Jenis yang menentukan itu sendiri tidak perlu dapat digunakan XAML sebagai objek. Faktanya, pola umum adalah mendeklarasikan kelas layanan yang perannya adalah memiliki anggota yang dapat dilampirkan dan menerapkan perilaku terkait, tetapi tidak melayani fungsi lain seperti representasi UI. Untuk bagian berikut, placeholder PropertyName mewakili nama anggota anda yang dapat dilampirkan. Nama tersebut harus valid dalam Tata Bahasa XamlName.

Berhati-hatilah dengan tabrakan nama antara pola-pola ini dan metode jenis lainnya. Jika ada anggota yang cocok dengan salah satu pola, itu dapat ditafsirkan sebagai jalur penggunaan anggota yang dapat dilampirkan oleh prosesor XAML bahkan jika itu bukan niat Anda.

Aksesor GetPropertyName

Tanda tangan untuk aksesor GetPropertyName harus:

public static object GetPropertyName(object target)

  • Objek target dapat ditentukan sebagai jenis yang lebih spesifik dalam implementasi Anda. Anda dapat menggunakan ini untuk mencakup penggunaan anggota yang dapat dilampirkan; penggunaan di luar cakupan yang Anda maksudkan akan melemparkan pengecualian cast yang tidak valid yang kemudian muncul oleh kesalahan penguraian XAML. Nama target parameter bukan persyaratan, tetapi dinamai target berdasarkan konvensi di sebagian besar implementasi.

  • Nilai pengembalian dapat ditentukan sebagai jenis yang lebih spesifik dalam implementasi Anda.

Untuk mendukung sintaks teks yang TypeConverter diaktifkan untuk penggunaan atribut anggota yang dapat dilampirkan, terapkan TypeConverterAttribute ke GetPropertyName aksesor. Menerapkan ke get alih-alih set mungkin tampak tidak intuitif; namun, konvensi ini dapat mendukung konsep anggota yang dapat dilampirkan baca-saja yang dapat diserialisasikan, yang berguna dalam skenario perancang.

Aksesor SetPropertyName

Tanda tangan untuk aksesor SetPropertyName harus:

public static void SetPropertyName(object target, object value)

  • Objek target dapat ditentukan sebagai jenis yang lebih spesifik dalam implementasi Anda, dengan logika dan konsekuensi yang sama seperti yang dijelaskan di bagian sebelumnya.

  • Objek value dapat ditentukan sebagai jenis yang lebih spesifik dalam implementasi Anda.

Ingatlah bahwa nilai untuk metode ini adalah input yang berasal dari penggunaan XAML, biasanya dalam bentuk atribut. Dari formulir atribut harus ada dukungan pengonversi nilai untuk sintaks teks, dan Atribut Anda pada GetPropertyNameaksesor s.

Penyimpanan Anggota yang Dapat Dilampirkan

Metode aksesor biasanya tidak cukup untuk menyediakan sarana untuk menempatkan nilai anggota yang dapat dilampirkan ke dalam grafik objek, atau untuk mengambil nilai dari grafik objek dan menserialisasikannya dengan benar. Untuk menyediakan fungsionalitas ini, target objek dalam tanda tangan aksesor sebelumnya harus mampu menyimpan nilai. Mekanisme penyimpanan harus konsisten dengan prinsip anggota yang dapat dilampirkan bahwa anggota dapat dilampirkan ke target di mana anggota yang dapat dilampirkan tidak ada dalam daftar anggota. Layanan XAML .NET menyediakan teknik implementasi untuk penyimpanan anggota yang dapat dilampirkan melalui API IAttachedPropertyStore dan AttachablePropertyServices. IAttachedPropertyStore digunakan oleh penulis XAML untuk menemukan implementasi toko, dan harus diimplementasikan pada jenis yang merupakan target aksesor. API statis AttachablePropertyServices digunakan dalam isi aksesor, dan merujuk ke anggota yang dapat dilampirkan oleh AttachableMemberIdentifier.

Dengan benar, menarik jenis, anggota, dan rakitan Anda adalah penting untuk melaporkan informasi sistem jenis XAML ke Layanan XAML .NET. Melaporkan informasi sistem jenis XAML relevan jika salah satu situasi berikut berlaku:

  • Anda berniat untuk digunakan dengan sistem XAML yang secara langsung didasarkan pada pembaca XAML Layanan XAML .NET dan penulis XAML.
  • Anda menentukan atau menggunakan kerangka kerja pemanfaatan XAML yang didasarkan pada pembaca XAML dan penulis XAML tersebut.

Untuk daftar setiap atribut terkait XAML yang relevan untuk dukungan XAML dari jenis kustom Anda, lihat Atribut CLR Terkait XAML untuk Jenis dan Pustaka Kustom.

Penggunaan

Penggunaan jenis kustom mengharuskan pembuat markup harus memetakan awalan untuk namespace assembly dan CLR yang berisi jenis kustom. Prosedur ini tidak didokumenkan dalam topik ini.

Tingkat Akses

XAML menyediakan sarana untuk memuat dan membuat instans jenis yang memiliki internal tingkat akses. Kemampuan ini disediakan sehingga kode pengguna dapat menentukan jenisnya sendiri, lalu membuat instans kelas tersebut dari markup yang juga merupakan bagian dari cakupan kode pengguna yang sama.

Contoh dari WPF adalah setiap kali kode pengguna mendefinisikan UserControl yang dimaksudkan sebagai cara untuk merefaktor perilaku UI, tetapi bukan sebagai bagian dari mekanisme ekstensi yang mungkin tersirat dengan mendeklarasikan kelas pendukung dengan public tingkat akses. UserControl Seperti itu dapat dinyatakan dengan internal akses jika kode pencadangan dikompilasi ke dalam rakitan yang sama dari mana ia direferensikan sebagai jenis XAML.

Untuk aplikasi yang memuat XAML dengan kepercayaan penuh dan menggunakan XamlObjectWriter, memuat kelas dengan internal tingkat akses selalu diaktifkan.

Untuk aplikasi yang memuat XAML di bawah kepercayaan parsial, Anda dapat mengontrol karakteristik tingkat akses dengan menggunakan XamlAccessLevel API. Selain itu, mekanisme deferral (seperti sistem templat WPF) harus dapat menyebarluaskan izin tingkat akses apa pun dan mempertahankannya untuk evaluasi run time akhir; ini ditangani secara internal dengan meneruskan XamlAccessLevel informasi.

Implementasi WPF

WPF XAML menggunakan model akses kepercayaan parsial di mana jika BAML dimuat di bawah kepercayaan parsial, akses dibatasi untuk AssemblyAccessTo perakitan yang merupakan sumber BAML. Untuk penangguhan, WPF menggunakan IXamlObjectWriterFactory.GetParentSettings sebagai mekanisme untuk meneruskan informasi tingkat akses.

Dalam terminologi WPF XAML, jenis internal adalah jenis yang didefinisikan oleh rakitan yang sama yang juga mencakup XAML referensi. Jenis seperti itu dapat dipetakan melalui namespace XAML yang sengaja menghilangkan assembly= bagian dari pemetaan, misalnya, xmlns:local="clr-namespace:WPFApplication1". Jika BAML mereferensikan jenis internal dan jenis tersebut memiliki internal tingkat akses, ini menghasilkan GeneratedInternalTypeHelper kelas untuk rakitan. Jika Anda ingin menghindari GeneratedInternalTypeHelper, Anda harus menggunakan public tingkat akses, atau harus memperhitungkan kelas yang relevan ke dalam rakitan terpisah dan membuat perakitan itu bergantung.

Baca juga