Metadata Properti Dependensi
Sistem properti Windows Presentation Foundation (WPF) mencakup sistem pelaporan metadata yang melampaui apa yang dapat dilaporkan tentang properti melalui karakteristik refleksi atau general common language runtime (CLR). Metadata untuk properti dependensi juga dapat ditetapkan secara unik oleh kelas yang menentukan properti dependensi, dapat diubah ketika properti dependensi ditambahkan ke kelas yang berbeda, dan dapat ditimpa secara khusus oleh semua kelas turunan yang mewarisi properti dependensi dari kelas dasar yang menentukan.
Prasyarat
Topik ini mengasumsikan bahwa Anda memahami properti dependensi dari perspektif konsumen properti dependensi yang ada pada kelas WPF, dan telah membaca Gambaran Umum Properti Dependensi. Untuk mengikuti contoh dalam topik ini, Anda juga harus memahami XAML dan tahu cara menulis aplikasi WPF.
Cara Metadata Properti Dependensi Digunakan
Metadata properti dependensi ada sebagai objek yang dapat dikueri untuk memeriksa karakteristik properti dependensi. Metadata ini juga sering diakses oleh sistem properti karena memproses properti dependensi tertentu. Objek metadata untuk properti dependensi dapat berisi jenis informasi berikut:
Nilai default untuk properti dependensi, jika tidak ada nilai lain yang dapat ditentukan untuk properti dependensi berdasarkan nilai lokal, gaya, pewarisan, dll. Untuk diskusi menyeluruh tentang bagaimana nilai default berpartisipasi dalam prioritas yang digunakan oleh sistem properti saat menetapkan nilai untuk properti dependensi, lihat Prioritas Nilai Properti Dependensi.
Referensi ke implementasi panggilan balik yang memengaruhi perilaku koersi atau pemberitahuan perubahan berdasarkan per jenis pemilik. Perhatikan bahwa panggilan balik ini sering didefinisikan dengan tingkat akses nonpublik, sehingga mendapatkan referensi aktual dari metadata umumnya tidak dimungkinkan kecuali referensi berada dalam cakupan akses yang diizinkan. Untuk informasi selengkapnya tentang panggilan balik properti dependensi, lihat Panggilan Balik dan Validasi Properti Dependensi.
Jika properti dependensi yang dimaksud dianggap sebagai properti tingkat kerangka kerja WPF, metadata mungkin berisi karakteristik properti dependensi tingkat kerangka kerja WPF, yang melaporkan informasi dan status untuk layanan seperti mesin tata letak tingkat kerangka kerja WPF dan logika pewarisan properti. Untuk informasi selengkapnya tentang aspek metadata properti dependensi ini, lihat Metadata Properti Kerangka Kerja.
API Metadata
Jenis yang melaporkan sebagian besar informasi metadata yang digunakan oleh sistem properti adalah PropertyMetadata kelas . Instans metadata ditentukan secara opsional ketika properti dependensi terdaftar dengan sistem properti, dan dapat ditentukan lagi untuk jenis tambahan yang menambahkan diri mereka sebagai pemilik atau mengambil alih metadata yang mereka warisi dari definisi properti dependensi kelas dasar. (Untuk kasus di mana pendaftaran properti tidak menentukan metadata, default PropertyMetadata dibuat dengan nilai default untuk kelas tersebut.) Metadata terdaftar dikembalikan seperti PropertyMetadata saat Anda memanggil berbagai GetMetadata kelebihan beban yang mendapatkan metadata dari properti dependensi pada DependencyObject instans.
Kelas PropertyMetadata ini kemudian berasal dari untuk menyediakan metadata yang lebih spesifik untuk divisi arsitektur seperti kelas tingkat kerangka kerja WPF. UIPropertyMetadata menambahkan pelaporan animasi, dan FrameworkPropertyMetadata menyediakan properti tingkat kerangka kerja WPF yang disebutkan di bagian sebelumnya. Ketika properti dependensi terdaftar, properti tersebut dapat didaftarkan dengan kelas turunan ini PropertyMetadata . Ketika metadata diperiksa, jenis dasar PropertyMetadata berpotensi ditransmisikan ke kelas turunan sehingga Anda dapat memeriksa properti yang lebih spesifik.
Catatan
Karakteristik properti yang dapat ditentukan dalam FrameworkPropertyMetadata terkadang disebut dalam dokumentasi ini sebagai "bendera". Saat Anda membuat instans metadata baru untuk digunakan dalam pendaftaran properti dependensi atau penimpaan metadata, Anda menentukan nilai-nilai ini menggunakan enumerasi FrameworkPropertyMetadataOptions berlapis dan kemudian Anda menyediakan nilai enumerasi yang mungkin digabungkan ke FrameworkPropertyMetadata konstruktor. Namun, setelah dibangun, karakteristik opsi ini diekspos dalam FrameworkPropertyMetadata sebagai serangkaian properti Boolean daripada membangun nilai enumerasi. Properti Boolean memungkinkan Anda memeriksa setiap kondisional, daripada mengharuskan Anda menerapkan masker ke nilai enumerasi bertingkat untuk mendapatkan informasi yang Anda minati. Konstruktor menggunakan yang digabungkan FrameworkPropertyMetadataOptions untuk menjaga panjang tanda tangan konstruktor tetap wajar, sedangkan metadata yang dibangun aktual mengekspos properti diskrit untuk membuat kueri metadata lebih intuitif.
Kapan Harus Mengambil Alih Metadata, Kapan Memperoleh Kelas
Sistem properti WPF telah menetapkan kemampuan untuk mengubah beberapa karakteristik properti dependensi tanpa mengharuskannya untuk sepenuhnya diimplementasikan kembali. Ini dicapai dengan membuat instans metadata properti yang berbeda untuk properti dependensi seperti yang ada pada jenis tertentu. Perhatikan bahwa sebagian besar properti dependensi yang ada bukan properti virtual, jadi secara ketat berbicara "mengimplementasikan ulang" properti tersebut pada kelas yang diwariskan hanya dapat dicapai dengan membayangi anggota yang ada.
Jika skenario yang Anda coba aktifkan untuk properti dependensi pada jenis tidak dapat dicapai dengan memodifikasi karakteristik properti dependensi yang ada, maka mungkin perlu untuk membuat kelas turunan, lalu untuk mendeklarasikan properti dependensi kustom pada kelas turunan Anda. Properti dependensi kustom berulah identik dengan properti dependensi yang ditentukan oleh API WPF. Untuk detail selengkapnya tentang properti dependensi kustom, lihat Properti Dependensi Kustom.
Salah satu karakteristik penting dari properti dependensi yang tidak dapat Anda ambil alih adalah jenis nilainya. Jika Anda mewarisi properti dependensi yang memiliki perkiraan perilaku yang Anda butuhkan, tetapi Anda memerlukan jenis yang berbeda untuk itu, Anda harus menerapkan properti dependensi kustom dan mungkin menautkan properti melalui konversi jenis atau implementasi lain di kelas kustom Anda. Selain itu, Anda tidak dapat menggantikan ValidateValueCallback, karena panggilan balik ini ada di bidang pendaftaran itu sendiri dan bukan dalam metadatanya.
Skenario untuk Mengubah Metadata yang Ada
Jika Anda bekerja dengan metadata properti dependensi yang ada, satu skenario umum untuk mengubah metadata properti dependensi adalah mengubah nilai default. Mengubah atau menambahkan panggilan balik sistem properti adalah skenario yang lebih canggih. Anda mungkin ingin melakukan ini jika implementasi kelas turunan Anda memiliki keterkaitan yang berbeda antara properti dependensi. Salah satu syarat memiliki model pemrograman yang mendukung penggunaan kode dan deklaratif adalah bahwa properti harus memungkinkan diatur dalam urutan apa pun. Dengan demikian setiap properti dependen perlu diatur tepat waktu tanpa konteks dan tidak dapat mengandalkan mengetahui urutan pengaturan seperti mungkin ditemukan di konstruktor. Untuk informasi selengkapnya tentang aspek sistem properti ini, lihat Panggilan Balik dan Validasi Properti Dependensi. Perhatikan bahwa panggilan balik validasi bukan bagian dari metadata; mereka adalah bagian dari pengidentifikasi properti dependensi. Oleh karena itu, panggilan balik validasi tidak dapat diubah dengan mengambil alih metadata.
Dalam beberapa kasus, Anda mungkin juga ingin mengubah opsi metadata properti tingkat kerangka kerja WPF pada properti dependensi yang ada. Opsi ini mengkomunikasikan kondisi tertentu yang diketahui tentang properti tingkat kerangka kerja WPF ke proses tingkat kerangka kerja WPF lainnya seperti sistem tata letak. Mengatur opsi umumnya dilakukan hanya saat mendaftarkan properti dependensi baru, tetapi juga dimungkinkan untuk mengubah metadata properti tingkat kerangka kerja WPF sebagai bagian OverrideMetadata dari atau AddOwner panggilan. Untuk nilai tertentu yang akan digunakan dan informasi selengkapnya, lihat Metadata Properti Kerangka Kerja. Untuk informasi selengkapnya yang berkaitan dengan bagaimana opsi ini harus diatur untuk properti dependensi yang baru terdaftar, lihat Properti Dependensi Kustom.
Mengesampingkan Metadata
Tujuan penimpaan metadata terutama agar Anda memiliki kesempatan untuk mengubah berbagai perilaku turunan metadata yang diterapkan ke properti dependensi seperti yang ada pada jenis Anda. Alasan untuk ini dijelaskan secara lebih rinci di bagian Metadata . Untuk informasi selengkapnya termasuk beberapa contoh kode, lihat Mengambil alih Metadata untuk Properti Dependensi.
Metadata properti dapat disediakan untuk properti dependensi selama panggilan pendaftaran (Register). Namun, dalam banyak kasus, Anda mungkin ingin menyediakan metadata khusus jenis untuk kelas Anda saat mewarisi properti dependensi tersebut. Anda dapat melakukan ini dengan memanggil OverrideMetadata metode . Misalnya dari API WPF, FrameworkElement kelas adalah jenis yang pertama kali mendaftarkan Focusable properti dependensi. Control Tetapi kelas mengambil alih metadata untuk properti dependensi untuk memberikan nilai default awalnya sendiri, mengubahnya dari false
ke true
, dan sebaliknya menggunakan kembali implementasi asliFocusable.
Saat Anda mengambil alih metadata, karakteristik metadata yang berbeda digabungkan atau diganti.
PropertyChangedCallback digabungkan. Jika Anda menambahkan panggilan balik baru PropertyChangedCallbackdisimpan dalam metadata. Jika Anda tidak menentukan PropertyChangedCallback dalam penimpaan PropertyChangedCallback , nilai dipromosikan sebagai referensi dari leluhur terdekat yang menentukannya dalam metadata.
Perilaku sistem properti aktual untuk PropertyChangedCallback adalah bahwa implementasi untuk semua pemilik metadata dalam hierarki dipertahankan dan ditambahkan ke tabel, dengan urutan eksekusi oleh sistem properti adalah bahwa panggilan balik kelas yang paling turunan dipanggil terlebih dahulu.
DefaultValue diganti. Jika Anda tidak menentukan DefaultValue dalam penimpaan DefaultValue , nilai berasal dari leluhur terdekat yang menentukannya dalam metadata.
CoerceValueCallback implementasi diganti. Jika Anda menambahkan panggilan balik baru CoerceValueCallbackdisimpan dalam metadata. Jika Anda tidak menentukan CoerceValueCallback dalam penimpaan CoerceValueCallback , nilai dipromosikan sebagai referensi dari leluhur terdekat yang menentukannya dalam metadata.
Perilaku sistem properti adalah bahwa hanya CoerceValueCallback metadata langsung yang dipanggil. Tidak ada referensi ke implementasi lain CoerceValueCallback dalam hierarki yang dipertahankan.
Perilaku ini diimplementasikan oleh Merge, dan dapat diambil alih pada kelas metadata turunan.
Mengesampingkan Metadata Properti Terlampir
Di WPF, properti terlampir diimplementasikan sebagai properti dependensi. Ini berarti bahwa mereka juga memiliki metadata properti, yang dapat diambil alih oleh masing-masing kelas. Pertimbangan cakupan untuk properti terlampir di WPF umumnya adalah bahwa setiap DependencyObject dapat memiliki properti terlampir yang diatur padanya. Oleh karena itu, setiap DependencyObject kelas turunan dapat mengambil alih metadata untuk properti terlampir apa pun, karena mungkin diatur pada instans kelas. Anda dapat mengambil alih nilai default, panggilan balik, atau properti pelaporan karakteristik tingkat kerangka kerja WPF. Jika properti terlampir diatur pada instans kelas Anda, karakteristik metadata properti penggantian tersebut akan berlaku. Misalnya, Anda dapat mengambil alih nilai default, sehingga nilai penimpaan Anda dilaporkan sebagai nilai properti terlampir pada instans kelas Anda, setiap kali properti tidak diatur sebaliknya.
Catatan
Properti Inherits tidak relevan untuk properti terlampir.
Menambahkan Kelas sebagai Pemilik Properti Dependensi yang Ada
Kelas dapat menambahkan dirinya sebagai pemilik properti dependensi yang telah terdaftar, dengan menggunakan metode .AddOwner Ini memungkinkan kelas untuk menggunakan properti dependensi yang awalnya didaftarkan untuk jenis yang berbeda. Kelas penambahan biasanya bukan kelas turunan dari jenis yang pertama kali mendaftarkan properti dependensi tersebut sebagai pemilik. Secara efektif, ini memungkinkan kelas Anda dan kelas turunannya untuk "mewarisi" implementasi properti dependensi tanpa kelas pemilik asli dan kelas penambahan berada dalam hierarki kelas sejati yang sama. Selain itu, kelas penambahan (dan semua kelas turunan juga) kemudian dapat menyediakan metadata khusus jenis untuk properti dependensi asli.
Selain menambahkan dirinya sebagai pemilik melalui metode utilitas sistem properti, kelas penambahan harus menyatakan anggota publik tambahan pada dirinya sendiri untuk membuat properti dependensi] peserta penuh dalam sistem properti dengan paparan kode dan markup. Kelas yang menambahkan properti dependensi yang ada memiliki tanggung jawab yang sama sejauh mengekspos model objek untuk properti dependensi tersebut seperti halnya kelas yang menentukan properti dependensi kustom baru. Anggota pertama yang diekspos adalah bidang pengidentifikasi properti dependensi. Bidang ini harus berupa public static readonly
bidang jenis DependencyProperty, yang ditetapkan ke nilai AddOwner pengembalian panggilan. Anggota kedua yang ditentukan adalah properti "wrapper" common language runtime (CLR). Pembungkus membuatnya jauh lebih nyaman untuk memanipulasi properti dependensi Anda dalam kode (Anda menghindari panggilan ke SetValue setiap kali, dan dapat melakukan panggilan itu hanya sekali di pembungkus itu sendiri). Pembungkus diimplementasikan secara identik dengan cara penerapannya jika Anda mendaftarkan properti dependensi kustom. Untuk informasi selengkapnya tentang menerapkan properti dependensi, lihat Properti Dependensi Kustom dan Menambahkan Jenis Pemilik untuk Properti Dependensi.
AddOwner dan Properti Terlampir
Anda dapat memanggil AddOwner properti dependensi yang didefinisikan sebagai properti terlampir oleh kelas pemilik. Umumnya alasan untuk melakukan ini adalah untuk mengekspos properti yang dilampirkan sebelumnya sebagai properti dependensi yang tidak terpasang. Anda kemudian akan mengekspos AddOwner nilai pengembalian sebagai public static readonly
bidang untuk digunakan sebagai pengidentifikasi properti dependensi, dan akan menentukan properti "pembungkus" yang sesuai sehingga properti muncul di tabel anggota dan mendukung penggunaan properti yang tidak terpasang di kelas Anda.
Baca juga
.NET Desktop feedback