TypeConverters dan XAML

Topik ini memperkenalkan tujuan konversi jenis dari string sebagai fitur bahasa XAML umum. Dalam .NET Framework, TypeConverter kelas ini melayani tujuan tertentu sebagai bagian dari implementasi untuk kelas kustom terkelola yang dapat digunakan sebagai nilai properti dalam penggunaan atribut XAML. Jika Anda menulis kelas kustom, dan Anda ingin instans kelas Anda dapat digunakan sebagai nilai atribut yang dapat ditetapkan XAML, Anda mungkin perlu menerapkan TypeConverterAttribute ke kelas Anda, menulis kelas kustom TypeConverter , atau keduanya.

Konsep Konversi Jenis

Nilai XAML dan String

Saat Anda menetapkan nilai atribut dalam file XAML, jenis awal nilai tersebut adalah string dalam teks murni. Bahkan primitif lain seperti Double awalnya adalah string teks ke prosesor XAML.

Prosesor XAML membutuhkan dua informasi untuk memproses nilai atribut. Bagian pertama dari informasi adalah jenis nilai properti yang sedang diatur. String apa pun yang mendefinisikan nilai atribut dan yang diproses dalam XAML pada akhirnya harus dikonversi atau diselesaikan ke nilai jenis tersebut. Jika nilai adalah primitif yang dipahami oleh pengurai XAML (seperti nilai numerik), konversi langsung string akan dicoba. Jika nilai adalah enumerasi, string digunakan untuk memeriksa kecocokan nama dengan konstanta bernama dalam enumerasi tersebut. Jika nilainya bukan primitif yang dipahami pengurai atau enumerasi, maka jenis yang dimaksud harus dapat memberikan instans jenis, atau nilai, berdasarkan string yang dikonversi. Ini dilakukan dengan menunjukkan kelas pengonversi jenis. Pengonversi jenis secara efektif adalah kelas pembantu untuk menyediakan nilai kelas lain, baik untuk skenario XAML dan juga berpotensi untuk panggilan kode dalam kode .NET.

Menggunakan Perilaku Konversi Jenis yang Ada di XAML

Tergantung pada keakraban Anda dengan konsep XAML yang mendasar, Anda mungkin sudah menggunakan perilaku konversi jenis dalam aplikasi dasar XAML tanpa menyadarinya. Misalnya, WPF mendefinisikan ratusan properti yang mengambil nilai jenis Point. Point adalah nilai yang menjelaskan koordinat dalam ruang koordinat dua dimensi, dan benar-benar hanya memiliki dua properti penting: X dan Y. Saat Anda menentukan titik di XAML, Anda menentukannya sebagai string dengan pemisah (biasanya koma) antara nilai dan Y yang X Anda berikan. Sebagai contoh: <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>.

Bahkan jenis Point sederhana ini dan penggunaan sederhananya di XAML melibatkan pengonversi jenis. Dalam hal ini adalah kelas PointConverter.

Pengonversi jenis untuk Point ditentukan pada tingkat kelas menyederhanakan penggunaan markup dari semua properti yang mengambil Point. Tanpa pengonversi jenis di sini, Anda akan memerlukan markup yang jauh lebih verbose berikut untuk contoh yang sama yang ditunjukkan sebelumnya:

<LinearGradientBrush>
  <LinearGradientBrush.StartPoint>
    <Point X="0" Y="0"/>
  </LinearGradientBrush.StartPoint>
  <LinearGradientBrush.EndPoint>
    <Point X="1" Y="1"/>
  </LinearGradientBrush.EndPoint>
</LinearGradientBrush>

Apakah akan menggunakan string konversi jenis atau sintaks yang lebih setara verbose umumnya adalah pilihan gaya pengkodean. Alur kerja alat XAML Anda mungkin juga memengaruhi bagaimana nilai diatur. Beberapa alat XAML cenderung memancarkan bentuk markup yang paling verbose karena lebih mudah untuk pulang pergi ke tampilan desainer atau mekanisme serialisasinya sendiri.

Pengonversi jenis yang ada umumnya dapat ditemukan pada jenis WPF dan .NET Framework dengan memeriksa kelas (atau properti) untuk keberadaan yang diterapkan TypeConverterAttribute. Atribut ini akan memberi nama kelas yang merupakan pengonversi jenis pendukung untuk nilai jenis tersebut, untuk tujuan XAML serta kemungkinan tujuan lainnya.

Jenis Konverter dan Ekstensi Markup

Ekstensi markup dan pengonversi jenis mengisi peran ortogonal dalam hal perilaku prosesor XAML dan skenario yang diterapkan. Meskipun konteks tersedia untuk penggunaan ekstensi markup, perilaku konversi jenis properti di mana ekstensi markup menyediakan nilai umumnya tidak diperiksa dalam implementasi ekstensi markup. Dengan kata lain, bahkan jika ekstensi markup mengembalikan string teks sebagai outputnya ProvideValue , perilaku konversi jenis pada string tersebut sebagaimana diterapkan ke properti tertentu atau jenis nilai properti tidak dipanggil, Umumnya, tujuan ekstensi markup adalah untuk memproses string dan mengembalikan objek tanpa konverter jenis apa pun yang terlibat.

Salah satu situasi umum di mana ekstensi markup diperlukan daripada pengonversi jenis adalah membuat referensi ke objek yang sudah ada. Yang terbaik, pengonversi jenis stateless hanya dapat menghasilkan instans baru, yang mungkin tidak diinginkan. Untuk informasi selengkapnya tentang ekstensi markup, lihat Ekstensi Markup dan WPF XAML.

Pengonversi Jenis Asli

Dalam implementasi WPF dan .NET Framework dari parser XAML, ada jenis tertentu yang memiliki penanganan konversi jenis asli, namun bukan jenis yang mungkin secara konvensional dianggap sebagai primitif. Contoh jenis tersebut adalah DateTime. Alasan untuk ini didasarkan pada cara kerja arsitektur .NET Framework: jenis DateTime didefinisikan dalam mscorlib, pustaka paling dasar di .NET. DateTime tidak diizinkan untuk dikaitkan dengan atribut yang berasal dari rakitan lain yang memperkenalkan dependensi (TypeConverterAttribute berasal dari Sistem) sehingga mekanisme penemuan pengonversi jenis biasa dengan attributing tidak dapat didukung. Sebaliknya, parser XAML memiliki daftar jenis yang membutuhkan pemrosesan asli dan memproses ini mirip dengan bagaimana primitif sejati diproses. (Dalam hal DateTime ini melibatkan panggilan ke Parse.)

Menerapkan Pengonversi Tipe

TypeConverter

Dalam contoh yang Point diberikan sebelumnya, kelas PointConverter disebutkan. Untuk implementasi .NET XAML, semua pengonversi jenis yang digunakan untuk tujuan XAML adalah kelas yang berasal dari kelas TypeConverterdasar . Kelas TypeConverter ada dalam versi .NET Framework yang mendahului keberadaan XAML; salah satu penggunaan aslinya adalah menyediakan konversi string untuk dialog properti di desainer visual. Untuk XAML, peran TypeConverter diperluas untuk menyertakan menjadi kelas dasar untuk konversi ke string dan dari string yang memungkinkan penguraian nilai atribut string, dan mungkin memproses nilai run-time dari properti objek tertentu kembali ke string untuk serialisasi sebagai atribut.

TypeConverter menentukan empat anggota yang relevan untuk mengonversi ke dan dari string untuk tujuan pemrosesan XAML:

Dari jumlah tersebut, metode yang paling penting adalah ConvertFrom. Metode ini mengonversi string input ke jenis objek yang diperlukan. Secara ketat, ConvertFrom metode ini dapat diimplementasikan untuk mengonversi berbagai jenis yang jauh lebih luas menjadi jenis tujuan yang dimaksudkan konverter, dan dengan demikian melayani tujuan yang melampaui XAML seperti mendukung konversi run-time, tetapi untuk tujuan XAML itu hanya jalur kode yang dapat memproses String input yang penting.

Metode terpenting berikutnya adalah ConvertTo. Jika aplikasi dikonversi ke representasi markup (misalnya, jika disimpan ke XAML sebagai file), ConvertTo bertanggung jawab untuk menghasilkan representasi markup. Dalam hal ini, jalur kode yang penting untuk XAML adalah ketika Anda melewati destinationType .String

CanConvertTo dan CanConvertFrom merupakan metode dukungan yang digunakan saat layanan meminta kemampuan TypeConverter implementasi. Anda harus menerapkan metode ini untuk mengembalikan true kasus khusus jenis yang metode konversi yang setara dari dukungan pengonversi Anda. Untuk tujuan XAML, ini umumnya berarti jenisnya String .

Pengonversi Informasi dan Jenis Budaya untuk XAML

Setiap TypeConverter implementasi dapat memiliki interpretasi sendiri tentang apa yang merupakan string yang valid untuk konversi, dan juga dapat menggunakan atau mengabaikan deskripsi jenis yang diteruskan sebagai parameter. Ada pertimbangan penting sehubungan dengan budaya dan konversi jenis XAML. Menggunakan string yang dapat dilokalkan karena nilai atribut sepenuhnya didukung oleh XAML. Tetapi menggunakan string yang dapat dilokalkan sebagai input pengonversi jenis dengan persyaratan budaya tertentu tidak didukung, karena pengonversi jenis untuk nilai atribut XAML melibatkan perilaku penguraian bahasa tetap yang harus dilakukan, menggunakan en-US budaya. Untuk informasi lebih lanjut tentang alasan desain untuk pembatasan ini, Anda harus berkonsultasi dengan spesifikasi bahasa XAML ([MS-XAML].

Sebagai contoh di mana budaya dapat menjadi masalah, beberapa budaya menggunakan koma sebagai pemisah titik desimal mereka untuk angka. Ini akan bertabrakan dengan perilaku yang dimiliki banyak konverter jenis WPF XAML, yaitu menggunakan koma sebagai pemisah (berdasarkan preseden historis seperti formulir X,Y umum, atau daftar yang dibatasi koma). Bahkan meneruskan budaya di XAML sekitarnya (pengaturan Language atau xml:lang ke sl-SI budaya, contoh budaya yang menggunakan koma untuk desimal dengan cara ini) tidak menyelesaikan masalah.

Menerapkan ConvertFrom

Agar dapat digunakan sebagai TypeConverter implementasi yang mendukung XAML, metode untuk pengonversi tersebut ConvertFrom harus menerima string sebagai value parameter. Jika string dalam format yang valid, dan dapat dikonversi oleh TypeConverter implementasi, maka objek yang dikembalikan harus mendukung transmisi ke jenis yang diharapkan oleh properti . Jika tidak, ConvertFrom implementasi harus mengembalikan null.

Setiap TypeConverter implementasi dapat memiliki interpretasi sendiri tentang apa yang merupakan string yang valid untuk konversi, dan juga dapat menggunakan atau mengabaikan deskripsi jenis atau konteks budaya yang diteruskan sebagai parameter. Namun, pemrosesan WPF XAML mungkin tidak meneruskan nilai ke konteks deskripsi jenis dalam semua kasus, dan juga mungkin tidak meneruskan budaya berdasarkan xml:lang.

Catatan

Jangan gunakan karakter kurung kurawal, terutama {, sebagai elemen yang mungkin dari format string Anda. Karakter ini dicadangkan sebagai entri dan keluar untuk urutan ekstensi markup.

Mengimplementasikan ConvertTo

ConvertTo berpotensi digunakan untuk dukungan serialisasi. Dukungan serialisasi melalui ConvertTo untuk jenis kustom Anda dan pengonversi jenisnya bukan persyaratan absolut. Namun, jika Anda menerapkan kontrol, atau menggunakan serialisasi sebagai bagian dari fitur atau desain kelas Anda, Anda harus menerapkan ConvertTo.

Agar dapat digunakan sebagai TypeConverter implementasi yang mendukung XAML, metode untuk pengonversi tersebut ConvertTo harus menerima instans jenis (atau nilai) yang didukung sebagai value parameter . destinationType Ketika parameter adalah jenis String, maka objek yang dikembalikan harus dapat ditransmisikan sebagai String. String yang dikembalikan harus mewakili nilai serial dari value. Idealnya, format serialisasi yang Anda pilih harus mampu menghasilkan nilai yang sama jika string tersebut ConvertFrom diteruskan ke implementasi pengonversi yang sama, tanpa kehilangan informasi yang signifikan.

Jika nilai tidak dapat diserialisasikan, atau pengonversi tidak mendukung serialisasi, ConvertTo implementasi harus mengembalikan null, dan diizinkan untuk melemparkan pengecualian dalam kasus ini. Tetapi jika Anda melemparkan pengecualian, Anda harus melaporkan ketidakmampuan untuk menggunakan konversi tersebut sebagai bagian dari implementasi Anda CanConvertTo sehingga praktik terbaik pemeriksaan dengan CanConvertTo terlebih dahulu untuk menghindari pengecualian didukung.

Jika destinationType parameter tidak berjenis String, Anda dapat memilih penanganan pengonversi Anda sendiri. Biasanya, Anda akan kembali ke penanganan implementasi dasar, yang di paling ConvertTo dasar menimbulkan pengecualian tertentu.

Menerapkan CanConvertTo

Implementasi Anda CanConvertTo harus kembali true untuk destinationType jenis String, dan jika tidak, tangguhkan ke implementasi dasar.

Menerapkan CanConvertFrom

Implementasi Anda CanConvertFrom harus kembali true untuk sourceType jenis String, dan jika tidak, tangguhkan ke implementasi dasar.

Menerapkan TypeConverterAttribute

Agar pengonversi jenis kustom Anda digunakan sebagai pengonversi jenis bertindak untuk kelas kustom oleh prosesor XAML, Anda harus menerapkannya TypeConverterAttribute ke definisi kelas Anda. ConverterTypeName yang Anda tentukan melalui atribut harus berupa nama jenis pengonversi jenis kustom Anda. Dengan atribut ini diterapkan, ketika prosesor XAML menangani nilai di mana jenis properti menggunakan jenis kelas kustom Anda, ia dapat memasukkan string dan mengembalikan instans objek.

Anda juga dapat menyediakan pengonversi jenis berdasarkan per properti. Alih-alih menerapkan TypeConverterAttribute ke definisi kelas, terapkan ke definisi properti (definisi utama, bukan implementasi di get/set dalamnya). Jenis properti harus cocok dengan jenis yang diproses oleh pengonversi tipe kustom Anda. Dengan atribut ini diterapkan, ketika prosesor XAML menangani nilai properti tersebut, ia dapat memproses string input dan mengembalikan instans objek. Teknik pengonversi jenis per properti sangat berguna jika Anda memilih untuk menggunakan jenis properti dari Microsoft .NET Framework atau dari beberapa pustaka lain di mana Anda tidak dapat mengontrol definisi kelas dan tidak dapat menerapkannya TypeConverterAttribute di sana.

Baca juga