Gambaran umum properti dependensi
Windows Presentation Foundation (WPF) menyediakan serangkaian layanan yang dapat digunakan untuk memperluas fungsionalitas properti jenis. Secara kolektif, layanan ini biasanya disebut sebagai sistem properti WPF. Properti yang didukung oleh sistem properti WPF dikenal sebagai properti dependensi. Gambaran umum ini menjelaskan sistem properti WPF dan kemampuan properti dependensi. Ini termasuk cara menggunakan properti dependensi yang ada di XAML dan dalam kode. Gambaran umum ini juga memperkenalkan aspek khusus properti dependensi, seperti metadata properti dependensi, dan cara membuat properti dependensi Anda sendiri di kelas kustom.
Prasyarat
Topik ini mengasumsikan bahwa Anda memiliki beberapa pengetahuan dasar tentang sistem jenis .NET dan pemrograman berorientasi objek. Untuk mengikuti contoh dalam topik ini, Anda juga harus memahami XAML dan tahu cara menulis aplikasi WPF. Untuk informasi selengkapnya, lihat Panduan: Aplikasi desktop WPF pertama saya.
Properti dependensi dan properti CLR
Di WPF, properti biasanya diekspos sebagai properti .NET standar. Pada tingkat dasar, Anda dapat berinteraksi dengan properti ini secara langsung dan tidak pernah tahu bahwa properti tersebut diimplementasikan sebagai properti dependensi. Namun, Anda harus terbiasa dengan beberapa atau semua fitur sistem properti WPF, sehingga Anda dapat memanfaatkan fitur-fitur ini.
Tujuan properti dependensi adalah untuk memberikan cara untuk menghitung nilai properti berdasarkan nilai input lain. Input lain ini mungkin mencakup properti sistem seperti tema dan preferensi pengguna, mekanisme penentuan properti just-in-time seperti pengikatan data dan animasi/papan cerita, templat multi-penggunaan seperti sumber daya dan gaya, atau nilai yang dikenal melalui hubungan induk-anak dengan elemen lain di pohon elemen. Selain itu, properti dependensi dapat diimplementasikan untuk menyediakan validasi mandiri, nilai default, panggilan balik yang memantau perubahan pada properti lain, dan sistem yang dapat memaksa nilai properti berdasarkan informasi runtime yang berpotensi. Kelas turunan juga dapat mengubah beberapa karakteristik spesifik properti yang ada dengan mengambil alih metadata properti dependensi, daripada mengesampingkan implementasi aktual dari properti yang ada atau membuat properti baru.
Dalam referensi SDK, Anda dapat mengidentifikasi properti mana yang merupakan properti dependensi dengan adanya bagian Informasi Properti Dependensi pada halaman referensi terkelola untuk properti tersebut. Bagian Informasi Properti Dependensi menyertakan tautan ke bidang pengidentifikasi untuk properti dependensi tersebut DependencyProperty , dan juga menyertakan daftar opsi metadata yang diatur untuk properti tersebut, informasi penggantian per kelas, dan detail lainnya.
Properti dependensi kembali properti CLR
Properti dependensi dan sistem properti WPF memperluas fungsionalitas properti dengan menyediakan jenis yang mendukung properti, sebagai implementasi alternatif untuk pola standar mendukung properti dengan bidang privat. Nama jenis ini adalah DependencyProperty. Jenis penting lainnya yang mendefinisikan sistem properti WPF adalah DependencyObject. DependencyObject menentukan kelas dasar yang dapat mendaftar dan memiliki properti dependensi.
Berikut ini mencantumkan terminologi yang digunakan dengan properti dependensi:
Properti dependensi: Properti yang didukung oleh DependencyProperty.
Pengidentifikasi properti dependensi:DependencyProperty Instans, yang diperoleh sebagai nilai pengembalian saat mendaftarkan properti dependensi, lalu disimpan sebagai anggota statis kelas. Pengidentifikasi ini digunakan sebagai parameter untuk banyak API yang berinteraksi dengan sistem properti WPF.
CLR "wrapper": Implementasi aktual get and set untuk properti. Implementasi ini menggabungkan pengidentifikasi properti dependensi dengan menggunakannya dalam GetValue panggilan dan SetValue , sehingga menyediakan dukungan untuk properti menggunakan sistem properti WPF.
Contoh berikut mendefinisikan IsSpinning
properti dependensi, dan menunjukkan hubungan DependencyProperty pengidentifikasi dengan properti yang didukungnya.
public static readonly DependencyProperty IsSpinningProperty =
DependencyProperty.Register(
"IsSpinning", typeof(Boolean),
typeof(MyCode)
);
public bool IsSpinning
{
get { return (bool)GetValue(IsSpinningProperty); }
set { SetValue(IsSpinningProperty, value); }
}
Public Shared ReadOnly IsSpinningProperty As DependencyProperty =
DependencyProperty.Register("IsSpinning",
GetType(Boolean),
GetType(MyCode))
Public Property IsSpinning() As Boolean
Get
Return CBool(GetValue(IsSpinningProperty))
End Get
Set(ByVal value As Boolean)
SetValue(IsSpinningProperty, value)
End Set
End Property
Konvensi penamaan properti dan bidang dukungannya DependencyProperty penting. Nama bidang selalu nama properti , dengan akhiran Property
ditambahkan. Untuk informasi selengkapnya tentang konvensi ini dan alasannya, lihat Properti Dependensi Kustom.
Mengatur nilai properti
Anda dapat mengatur properti baik dalam kode atau di XAML.
Mengatur nilai properti di XAML
Contoh XAML berikut menentukan warna latar belakang tombol sebagai merah. Contoh ini menggambarkan kasus di mana nilai string sederhana untuk atribut XAML dikonversi jenis oleh pengurai WPF XAML menjadi jenis WPF ( Color, dengan cara SolidColorBrush) dalam kode yang dihasilkan.
<Button Background="Red" Content="Button!"/>
XAML mendukung berbagai bentuk sintaks untuk mengatur properti. Sintaks mana yang akan digunakan untuk properti tertentu akan bergantung pada jenis nilai yang digunakan properti, serta faktor lain seperti keberadaan pengonversi jenis. Untuk informasi selengkapnya tentang sintaks XAML untuk pengaturan properti, lihat XAML dalam Sintaks WPF dan XAML Secara Terperinci.
Sebagai contoh sintaks non-atribut, contoh XAML berikut menunjukkan latar belakang tombol lain. Kali ini daripada mengatur warna solid sederhana, latar belakang diatur ke gambar, dengan elemen yang mewakili gambar tersebut dan sumber gambar tersebut ditentukan sebagai atribut elemen berlapis. Ini adalah contoh sintaks elemen properti.
<Button Content="Button!">
<Button.Background>
<ImageBrush ImageSource="wavy.jpg"/>
</Button.Background>
</Button>
Mengatur properti dalam kode
Mengatur nilai properti dependensi dalam kode biasanya hanya panggilan ke implementasi yang ditetapkan yang diekspos oleh "pembungkus" CLR.
Button myButton = new Button();
myButton.Width = 200.0;
Dim myButton As New Button()
myButton.Width = 200.0
Mendapatkan nilai properti juga pada dasarnya adalah panggilan ke implementasi "wrapper":
double whatWidth;
whatWidth = myButton.Width;
Dim whatWidth As Double
whatWidth = myButton.Width
Anda juga dapat memanggil API GetValue sistem properti dan SetValue secara langsung. Ini biasanya tidak diperlukan jika Anda menggunakan properti yang ada (pembungkus lebih nyaman, dan memberikan paparan properti yang lebih baik untuk alat pengembang), tetapi memanggil API secara langsung sesuai untuk skenario tertentu.
Properti juga dapat diatur di XAML dan kemudian diakses nanti dalam kode, melalui code-behind. Untuk detailnya, lihat Code-Behind dan XAML di WPF.
Fungsionalitas properti yang disediakan oleh properti dependensi
Properti dependensi menyediakan fungsionalitas yang memperluas fungsionalitas properti dibandingkan dengan properti yang didukung oleh bidang. Seringkali, fungsionalitas tersebut mewakili atau mendukung salah satu fitur spesifik berikut:
Sumber
Nilai properti dependensi dapat diatur dengan mereferensikan sumber daya. Sumber daya biasanya ditentukan sebagai Resources
nilai properti dari elemen akar halaman, atau aplikasi (lokasi ini memungkinkan akses paling nyaman ke sumber daya). Contoh berikut menunjukkan cara menentukan SolidColorBrush sumber daya.
<DockPanel.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</DockPanel.Resources>
Setelah sumber daya ditentukan, Anda dapat mereferensikan sumber daya dan menggunakannya untuk memberikan nilai properti:
<Button Background="{DynamicResource MyBrush}" Content="I am gold" />
Sumber daya khusus ini direferensikan sebagai DynamicResource Markup Extension (dalam WPF XAML, Anda dapat menggunakan referensi sumber daya statis atau dinamis). Untuk menggunakan referensi sumber daya dinamis, Anda harus mengatur ke properti dependensi, sehingga khususnya penggunaan referensi sumber daya dinamis yang diaktifkan oleh sistem properti WPF. Untuk informasi selengkapnya, lihat Sumber Daya XAML.
Catatan
Sumber daya diperlakukan sebagai nilai lokal, yang berarti bahwa jika Anda menetapkan nilai lokal lain, Anda akan menghilangkan referensi sumber daya. Untuk informasi selengkapnya, lihat Prioritas Nilai Properti Dependensi.
Pengikatan data
Properti dependensi dapat mereferensikan nilai melalui pengikatan data. Pengikatan data bekerja melalui sintaks ekstensi markup tertentu di XAML, atau Binding objek dalam kode. Dengan pengikatan data, penentuan nilai properti akhir ditangguhkan hingga durasi, saat nilai diperoleh dari sumber data.
Contoh berikut mengatur Content properti untuk Button, menggunakan pengikatan yang dideklarasikan dalam XAML. Pengikatan menggunakan konteks data yang diwariskan dan XmlDataProvider sumber data (tidak ditampilkan). Pengikatan itu sendiri menentukan properti sumber yang diinginkan dengan XPath dalam sumber data.
<Button Content="{Binding XPath=Team/@TeamName}"/>
Catatan
Pengikatan diperlakukan sebagai nilai lokal, yang berarti bahwa jika Anda menetapkan nilai lokal lain, Anda akan menghilangkan pengikatan. Untuk detailnya, lihat Prioritas Nilai Properti Dependensi.
Properti dependensi, atau DependencyObject kelas , tidak secara asli mendukung INotifyPropertyChanged untuk tujuan menghasilkan pemberitahuan perubahan DependencyObject nilai properti sumber untuk operasi pengikatan data. Untuk informasi selengkapnya tentang cara membuat properti untuk digunakan dalam pengikatan data yang dapat melaporkan perubahan pada target pengikatan data, lihat Gambaran Umum Pengikatan Data.
Gaya
Gaya dan templat adalah dua skenario utama yang memotivasi untuk menggunakan properti dependensi. Gaya sangat berguna untuk mengatur properti yang menentukan antarmuka pengguna aplikasi (UI). Gaya biasanya didefinisikan sebagai sumber daya di XAML. Gaya berinteraksi dengan sistem properti karena biasanya berisi "setter" untuk properti tertentu, serta "pemicu" yang mengubah nilai properti berdasarkan nilai real-time untuk properti lain.
Contoh berikut membuat gaya sederhana (yang akan didefinisikan di dalam Resources kamus, tidak ditampilkan), lalu menerapkan gaya tersebut langsung ke Style properti untuk Button. Setter dalam gaya mengatur Background properti untuk ditata Button ke hijau.
<Style x:Key="GreenButtonStyle">
<Setter Property="Control.Background" Value="Green"/>
</Style>
<Button Style="{StaticResource GreenButtonStyle}">I am green!</Button>
Untuk informasi selengkapnya, lihat Gaya dan Templat.
Animasi
Properti dependensi dapat dianimasikan. Saat animasi diterapkan dan berjalan, nilai animasi beroperasi dengan prioritas yang lebih tinggi daripada nilai apa pun (seperti nilai lokal) yang dimiliki properti.
Contoh berikut menganimasikan Background pada Button properti (secara teknis, Background dianimasikan dengan menggunakan sintaks elemen properti untuk menentukan kosong SolidColorBrush sebagai Background, maka Color properti tersebut SolidColorBrush adalah properti yang secara langsung dianimasikan).
<Button>I am animated
<Button.Background>
<SolidColorBrush x:Name="AnimBrush"/>
</Button.Background>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetName="AnimBrush"
Storyboard.TargetProperty="(SolidColorBrush.Color)"
From="Red" To="Green" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
Untuk informasi selengkapnya tentang menganimasikan properti, lihat Gambaran Umum Animasi dan Ringkasan Papan Cerita.
Penimpaan metadata
Anda dapat mengubah perilaku tertentu dari properti dependensi dengan mengambil alih metadata untuk properti tersebut ketika Anda berasal dari kelas yang awalnya mendaftarkan properti dependensi. Mengambil alih metadata bergantung pada DependencyProperty pengidentifikasi. Mengambil alih metadata tidak memerlukan pengisian ulang properti. Perubahan metadata ditangani secara asli oleh sistem properti; setiap kelas berpotensi menyimpan metadata individual untuk semua properti yang diwarisi dari kelas dasar, berdasarkan per jenis.
Contoh berikut mengambil alih metadata untuk properti DefaultStyleKeydependensi . Mengambil alih metadata properti dependensi khusus ini adalah bagian dari pola implementasi yang membuat kontrol yang dapat menggunakan gaya default dari tema.
public class SpinnerControl : ItemsControl
{
static SpinnerControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(SpinnerControl),
new FrameworkPropertyMetadata(typeof(SpinnerControl))
);
}
}
Public Class SpinnerControl
Inherits ItemsControl
Shared Sub New()
DefaultStyleKeyProperty.OverrideMetadata(GetType(SpinnerControl), New FrameworkPropertyMetadata(GetType(SpinnerControl)))
End Sub
End Class
Untuk informasi selengkapnya tentang mengambil alih atau mendapatkan metadata properti, lihat Metadata Properti Dependensi.
Warisan nilai properti
Elemen dapat mewarisi nilai properti dependensi dari induknya di pohon objek.
Catatan
Perilaku pewarisan nilai properti tidak diaktifkan secara global untuk semua properti dependensi, karena waktu perhitungan untuk pewarisan memang memiliki beberapa dampak performa. Pewarisan nilai properti biasanya hanya diaktifkan untuk properti di mana skenario tertentu menunjukkan bahwa pewarisan nilai properti sesuai. Anda dapat menentukan apakah properti dependensi mewarisi dengan melihat bagian Informasi Properti Dependensi untuk properti dependensi tersebut dalam referensi SDK.
Contoh berikut menunjukkan pengikatan, dan mengatur DataContext properti yang menentukan sumber pengikatan, yang tidak ditampilkan dalam contoh pengikatan sebelumnya. Setiap pengikatan berikutnya dalam objek anak tidak perlu menentukan sumbernya, mereka dapat menggunakan nilai yang diwariskan dari DataContext dalam objek induk StackPanel . (Atau, objek anak dapat memilih untuk secara langsung menentukan sendiri DataContext atau di SourceBinding, dan untuk sengaja tidak menggunakan nilai yang diwariskan untuk konteks data pengikatannya.)
<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource XmlTeamsSource}}">
<Button Content="{Binding XPath=Team/@TeamName}"/>
</StackPanel>
Untuk informasi selengkapnya, lihat Pewarisan Nilai Properti.
Integrasi perancang WPF
Kontrol kustom dengan properti yang diimplementasikan sebagai properti dependensi akan menerima dukungan WPF Designer untuk Visual Studio yang sesuai. Salah satu contohnya adalah kemampuan untuk mengedit properti dependensi langsung dan terlampir dengan jendela Properti . Untuk informasi selengkapnya, lihat Gambaran Umum Penulisan Kontrol.
Nilai properti dependensi didahulukan
Ketika Anda mendapatkan nilai properti dependensi, Anda berpotensi mendapatkan nilai yang ditetapkan pada properti tersebut melalui salah satu input berbasis properti lainnya yang berpartisipasi dalam sistem properti WPF. Prioritas nilai properti dependensi ada sehingga berbagai skenario tentang bagaimana properti mendapatkan nilainya dapat berinteraksi dengan cara yang dapat diprediksi.
Pertimbangkan contoh berikut. Contohnya mencakup gaya yang berlaku untuk semua tombol dan propertinya Background , tetapi kemudian juga menentukan satu tombol dengan nilai yang ditetapkan Background secara lokal.
Catatan
Dokumentasi SDK menggunakan istilah "nilai lokal" atau "nilai yang ditetapkan secara lokal" sesekali saat membahas properti dependensi. Nilai yang ditetapkan secara lokal adalah nilai properti yang diatur langsung pada instans objek dalam kode, atau sebagai atribut pada elemen di XAML.
Pada prinsipnya, untuk tombol pertama, properti diatur dua kali, tetapi hanya satu nilai yang berlaku: nilai dengan prioritas tertinggi. Nilai yang ditetapkan secara lokal memiliki prioritas tertinggi (kecuali untuk animasi yang sedang berjalan, tetapi tidak ada animasi yang berlaku dalam contoh ini) dan dengan demikian nilai yang ditetapkan secara lokal digunakan alih-alih nilai setter gaya untuk latar belakang pada tombol pertama. Tombol kedua tidak memiliki nilai lokal (dan tidak ada nilai lain dengan prioritas yang lebih tinggi daripada setter gaya) dan dengan demikian latar belakang di tombol tersebut berasal dari setter gaya.
<StackPanel>
<StackPanel.Resources>
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red"/>
</Style>
</StackPanel.Resources>
<Button Background="Green">I am NOT red!</Button>
<Button>I am styled red</Button>
</StackPanel>
Mengapa properti dependensi diutamakan ada?
Biasanya, Anda tidak ingin gaya selalu diterapkan dan mengaburkan bahkan nilai elemen individual yang ditetapkan secara lokal (jika tidak, akan sulit untuk menggunakan gaya atau elemen secara umum). Oleh karena itu, nilai yang berasal dari gaya beroperasi pada preseden yang lebih rendah daripada nilai yang ditetapkan secara lokal. Untuk daftar properti dependensi yang lebih menyeluruh dan asal nilai efektif properti dependensi, lihat Prioritas Nilai Properti Dependensi.
Catatan
Ada sejumlah properti yang ditentukan pada elemen WPF yang bukan properti dependensi. Menurut dan besar, properti diimplementasikan sebagai properti dependensi hanya ketika ada kebutuhan untuk mendukung setidaknya salah satu skenario yang diaktifkan oleh sistem properti: pengikatan data, gaya, animasi, dukungan nilai default, warisan, properti terlampir, atau pembatalan.
Pembelajaran selengkapnya tentang properti dependensi
Properti terlampir adalah jenis properti yang mendukung sintaksis khusus dalam XAML. Properti terlampir sering tidak memiliki korespondensi 1:1 dengan properti runtime bahasa umum (CLR), dan belum tentu merupakan properti dependensi. Tujuan umum properti terlampir adalah untuk memungkinkan elemen anak melaporkan nilai properti ke elemen induk, bahkan jika elemen induk dan elemen turunan tidak memiliki properti tersebut sebagai bagian dari daftar anggota kelas. Salah satu skenario utama adalah mengaktifkan elemen turunan untuk memberi tahu induk bagaimana elemen tersebut harus disajikan di UI; misalnya, lihat Dock atau Left. Untuk detailnya, lihat Gambaran Umum Properti Terlampir.
Pengembang komponen atau pengembang aplikasi mungkin ingin membuat properti dependensi mereka sendiri, untuk mengaktifkan kemampuan seperti pengikatan data atau dukungan gaya, atau untuk dukungan koersi pembatalan dan nilai. Untuk detailnya, lihat Properti Dependensi Kustom.
Pertimbangkan properti dependensi untuk menjadi properti publik, dapat diakses atau setidaknya dapat ditemukan oleh pemanggil apa pun yang memiliki akses ke instans. Untuk informasi selengkapnya, lihat Keamanan Properti Dependensi.
Baca juga
.NET Desktop feedback
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk