Bagikan melalui


Gambaran umum properti dependensi (WPF .NET)

Windows Presentation Foundation (WPF) menyediakan serangkaian layanan yang dapat digunakan untuk memperluas fungsionalitas properti jenis. Secara kolektif, layanan ini 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, 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.

Penting

Dokumentasi Panduan Desktop untuk .NET 7 dan .NET 6 sedang dibangun.

Prasyarat

Artikel ini mengasumsikan pengetahuan dasar tentang sistem jenis .NET dan pemrograman berorientasi objek. Untuk mengikuti contoh dalam artikel ini, ini membantu memahami XAML dan tahu cara menulis aplikasi WPF. Untuk informasi selengkapnya, lihat Tutorial: Membuat aplikasi WPF baru dengan .NET.

Properti dependensi dan properti CLR

Properti WPF biasanya diekspos sebagai properti .NET standar. Anda mungkin berinteraksi dengan properti ini pada tingkat dasar dan tidak pernah tahu bahwa properti tersebut diimplementasikan sebagai properti dependensi. Namun, keakraban dengan beberapa atau semua fitur sistem properti WPF, akan membantu Anda memanfaatkan fitur-fitur tersebut.

Tujuan properti dependensi adalah untuk memberikan cara untuk menghitung nilai properti berdasarkan nilai input lain, seperti:

  • Properti sistem, seperti tema dan preferensi pengguna.
  • Mekanisme penentuan properti just-in-time, seperti pengikatan data dan animasi/papan cerita.
  • Templat beberapa penggunaan, seperti sumber daya dan gaya.
  • Nilai yang diketahui melalui hubungan induk-turunan dengan elemen lain di pohon elemen.

Selain itu, properti dependensi dapat menyediakan:

  • Validasi mandiri.
  • Nilai default.
  • Panggilan balik yang memantau perubahan pada properti lain.
  • Sistem yang dapat memaksa nilai properti berdasarkan informasi runtime.

Kelas turunan dapat mengubah beberapa karakteristik properti yang ada dengan mengambil alih metadata properti dependensi, daripada mengesampingkan implementasi aktual properti yang ada atau membuat properti baru.

Di referensi SDK, Anda dapat mengidentifikasi properti dependensi dengan adanya bagian Informasi Properti Dependensi di halaman referensi terkelola untuk properti tersebut. Bagian Informasi Properti Dependensi menyertakan tautan ke bidang pengidentifikasi untuk properti dependensi tersebut DependencyProperty . Ini juga mencakup daftar opsi metadata untuk properti tersebut, informasi penimpaan 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 alternatif untuk pola standar mendukung properti dengan bidang privat. Nama jenis ini adalah DependencyProperty. Jenis penting lainnya yang mendefinisikan sistem properti WPF adalah DependencyObject, yang menentukan kelas dasar yang dapat mendaftar dan memiliki properti dependensi.

Berikut adalah beberapa terminologi yang umum digunakan:

  • Properti dependensi, yang merupakan properti yang didukung oleh DependencyProperty.

  • Pengidentifikasi properti dependensi, yang merupakan DependencyProperty instans yang diperoleh sebagai nilai pengembalian saat mendaftarkan properti dependensi, lalu disimpan sebagai anggota statis kelas. Banyak API yang berinteraksi dengan sistem properti WPF menggunakan pengidentifikasi properti dependensi sebagai parameter.

  • CLR "wrapper", yang merupakan get implementasi dan set untuk properti. Implementasi ini menggabungkan pengidentifikasi properti dependensi dengan menggunakannya dalam GetValue panggilan dan SetValue . Dengan cara ini, sistem properti WPF menyediakan dukungan untuk properti.

Contoh berikut mendefinisikan IsSpinning properti dependensi untuk memperlihatkan hubungan DependencyProperty pengidentifikasi dengan properti yang di-back.

public static readonly DependencyProperty IsSpinningProperty = DependencyProperty.Register(
    "IsSpinning", typeof(bool),
    typeof(MainWindow)
    );

public bool IsSpinning
{
    get => (bool)GetValue(IsSpinningProperty);
    set => SetValue(IsSpinningProperty, value);
}
Public Shared ReadOnly IsSpinningProperty As DependencyProperty =
    DependencyProperty.Register("IsSpinning", GetType(Boolean), GetType(MainWindow))

Public Property IsSpinning As Boolean
    Get
        Return GetValue(IsSpinningProperty)
    End Get
    Set(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 mengatur warna latar belakang tombol menjadi merah. Nilai string untuk atribut XAML dikonversi jenis oleh pengurai WPF XAML menjadi jenis WPF. Dalam kode yang dihasilkan, jenis WPF adalah Color, dengan cara SolidColorBrush.

<Button Content="I am red" Background="Red"/>

XAML mendukung beberapa formulir sintaks untuk mengatur properti. Sintaks mana yang digunakan untuk properti tertentu tergantung pada jenis nilai yang digunakan properti, dan faktor lain, seperti keberadaan pengonversi jenis. Untuk informasi selengkapnya tentang sintaks XAML untuk mengatur properti, lihat XAML dalam sintaks WPF dan XAML Secara terperinci.

Contoh XAML berikut menunjukkan latar belakang tombol lain yang menggunakan sintaks elemen properti alih-alih sintaks atribut. Daripada mengatur warna solid sederhana, XAML mengatur properti tombol Background ke gambar. Elemen mewakili gambar tersebut, dan atribut elemen berlapis menentukan sumber gambar.

<Button Content="I have an image background">
    <Button.Background>
        <ImageBrush ImageSource="stripes.jpg"/>
    </Button.Background>
</Button>

Mengatur properti dalam kode

Mengatur nilai properti dependensi dalam kode biasanya hanya panggilan ke implementasi yang set diekspos oleh "pembungkus" CLR:

Button myButton = new();
myButton.Width = 200.0;
Dim myButton As New Button With {
    .Width = 200.0
}

Mendapatkan nilai properti pada dasarnya adalah panggilan ke get implementasi "pembungkus":

double whatWidth = myButton.Width;
Dim whatWidth As Double = myButton.Width

Anda juga dapat memanggil API GetValue sistem properti dan SetValue secara langsung. Memanggil API secara langsung sesuai untuk beberapa skenario, tetapi biasanya tidak saat Anda menggunakan properti yang ada. Biasanya, pembungkus lebih nyaman, dan memberikan paparan properti yang lebih baik untuk alat pengembang.

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

Tidak seperti properti yang didukung oleh bidang, properti dependensi memperluas fungsionalitas properti. Seringkali, fungsionalitas yang ditambahkan mewakili atau mendukung salah satu fitur ini:

Sumber

Anda dapat mengatur nilai properti dependensi dengan mereferensikan sumber daya. Sumber daya biasanya ditentukan sebagai Resources nilai properti dari elemen akar halaman, atau aplikasi, karena lokasi ini menawarkan akses mudah ke sumber daya. Dalam contoh ini, kami menentukan SolidColorBrush sumber daya:

<StackPanel.Resources>
    <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</StackPanel.Resources>

Sekarang setelah sumber daya ditentukan, kita dapat mereferensikan sumber daya untuk memberikan nilai untuk Background properti:

<Button Background="{DynamicResource MyBrush}" Content="I am gold" />

Di WPF XAML, Anda dapat menggunakan referensi sumber daya statis atau dinamis. Sumber daya khusus ini direferensikan sebagai DynamicResource. Referensi sumber daya dinamis hanya dapat digunakan untuk mengatur 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, pada saat itu nilai diperoleh dari sumber data.

Contoh berikut mengatur Content properti untuk Button, dengan menggunakan pengikatan yang dideklarasikan dalam XAML. Pengikatan menggunakan konteks data yang diwariskan dan XmlDataProvider sumber data (tidak ditampilkan). Pengikatan itu sendiri menentukan properti sumber dalam sumber data dengan XPath.

<Button Content="{Binding Source={StaticResource TestData}, XPath=test[1]/@text}"/>

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 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 alasan kuat untuk menggunakan properti dependensi. Gaya sangat berguna untuk mengatur properti yang menentukan UI aplikasi. Gaya biasanya didefinisikan sebagai sumber daya di XAML. Gaya berinteraksi dengan sistem properti karena biasanya berisi "setter" untuk properti tertentu, dan "pemicu" yang mengubah nilai properti berdasarkan nilai runtime untuk properti lain.

Contoh berikut membuat gaya sederhana, yang akan ditentukan di dalam Resources kamus (tidak ditampilkan). Kemudian gaya tersebut diterapkan 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}" Content="I am green"/>

Untuk informasi selengkapnya, lihat Gaya dan templat.

Animasi

Properti dependensi dapat dianimasikan. Saat animasi yang diterapkan berjalan, nilai animasi memiliki prioritas yang lebih tinggi daripada nilai properti lainnya, termasuk nilai lokal.

Contoh berikut menganimasikan Background properti dari Button. Secara teknis, sintaks elemen properti menetapkan kosong SolidColorBrush sebagai Background, dan Color properti SolidColorBrush animasi.

<Button Content="I am animated">
    <Button.Background>
        <SolidColorBrush x:Name="AnimBrush"/>
    </Button.Background>
    <Button.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation
                        Storyboard.TargetName="AnimBrush" 
                        Storyboard.TargetProperty="(SolidColorBrush.Color)"
                        From="Blue" To="White" Duration="0:0:1" 
                        AutoReverse="True" RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

Untuk informasi selengkapnya tentang menganimasikan properti, lihat Gambaran umum animasi dan Ringkasan Storyboards.

Penimpaan metadata

Anda dapat mengubah perilaku tertentu dari properti dependensi dengan mengesampingkan metadatanya ketika Anda berasal dari kelas yang awalnya mendaftarkan properti dependensi. Mengambil alih metadata bergantung pada DependencyProperty pengidentifikasi dan tidak memerlukan pelengkapan 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 DefaultStyleKey properti dependensi. Mengambil alih metadata untuk properti dependensi khusus ini adalah bagian dari pola implementasi untuk 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 menimpa atau mengakses metadata untuk properti dependensi, lihat Mengambil alih metadata untuk 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 memengaruhi performa. Pewarisan nilai properti biasanya hanya diaktifkan dalam skenario yang menyarankan penerapan. Anda dapat memeriksa apakah properti dependensi mewarisi dengan melihat bagian Informasi Properti Dependensi untuk properti dependensi tersebut dalam referensi SDK.

Contoh berikut menunjukkan pengikatan yang menyertakan DataContext properti untuk menentukan sumber pengikatan. Jadi, pengikatan dalam objek anak tidak perlu menentukan sumber dan dapat menggunakan nilai yang diwariskan dari DataContext dalam objek induk StackPanel . Atau, objek anak dapat langsung menentukan sendiri DataContext atau di SourceBinding, dan tidak menggunakan nilai yang diwariskan.

<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource TestData}}">
    <Button Content="{Binding XPath=test[2]/@text}"/>
</StackPanel>

Untuk informasi selengkapnya, lihat Pewarisan nilai properti.

Integrasi perancang WPF

Kontrol kustom dengan properti yang diimplementasikan sebagai properti dependensi terintegrasi dengan baik dengan WPF Designer untuk Visual Studio. Salah satu contohnya adalah kemampuan untuk mengedit properti dependensi langsung dan terlampir di jendela Properti . Untuk informasi selengkapnya, lihat Gambaran umum penulisan kontrol.

Nilai properti dependensi didahulukan

Salah satu input berbasis properti dalam sistem properti WPF dapat mengatur nilai properti dependensi. Prioritas nilai properti dependensi ada sehingga berbagai skenario tentang bagaimana properti mendapatkan nilainya berinteraksi dengan cara yang dapat diprediksi.

Catatan

Dokumentasi SDK terkadang menggunakan istilah "nilai lokal" atau "nilai yang ditetapkan secara lokal" saat membahas properti dependensi. Nilai yang ditetapkan secara lokal adalah nilai properti yang diatur langsung pada instans objek dalam kode, atau sebagai atribut elemen di XAML.

Contoh berikutnya menyertakan gaya yang berlaku untuk Background properti tombol apa pun, tetapi menentukan satu tombol dengan properti yang diatur Background secara lokal. Secara teknis, tombol tersebut memiliki properti yang Background ditetapkan dua kali, meskipun hanya satu nilai yang berlaku—nilai dengan prioritas tertinggi. Nilai yang ditetapkan secara lokal memiliki prioritas tertinggi, kecuali untuk animasi yang sedang berjalan, yang tidak ada di sini. Jadi, tombol kedua menggunakan nilai yang ditetapkan secara lokal untuk Background properti , bukan nilai setter gaya. Tombol pertama tidak memiliki nilai lokal, atau nilai lain dengan prioritas yang lebih tinggi daripada setter gaya, sehingga menggunakan nilai setter gaya untuk Background properti .

<StackPanel>
    <StackPanel.Resources>
        <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Orange"/>
        </Style>
    </StackPanel.Resources>
    <Button>I am styled orange</Button>
    <Button Background="Pink">I am locally set to pink (not styled orange)</Button>
</StackPanel>

Mengapa properti dependensi diutamakan ada?

Nilai yang ditetapkan secara lokal lebih diutamakan daripada nilai setter gaya, yang mendukung kontrol lokal properti elemen. Untuk detailnya, lihat Prioritas nilai properti dependensi.

Catatan

Sejumlah properti yang ditentukan pada elemen WPF bukan properti dependensi, karena properti dependensi biasanya hanya diterapkan ketika fitur sistem properti WPF diperlukan. Fitur-fiturnya termasuk pengikatan data, gaya, animasi, dukungan nilai default, warisan, properti terlampir, dan pembatalan.

Pembelajaran selengkapnya tentang properti dependensi

  • Pengembang komponen atau pengembang aplikasi mungkin ingin membuat properti dependensi mereka sendiri untuk menambahkan kemampuan, seperti pengikatan data atau dukungan gaya, atau dukungan pembatalan dan pemahaman nilai. Untuk informasi selengkapnya, lihat Properti dependensi kustom.

  • Pertimbangkan properti dependensi untuk menjadi properti publik, dapat diakses atau ditemukan oleh penelepon apa pun dengan akses ke instans. Untuk informasi selengkapnya, lihat Keamanan 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 dan belum tentu merupakan properti dependensi. Tujuan utama properti terlampir adalah untuk memungkinkan elemen anak melaporkan nilai properti ke elemen induk, bahkan jika elemen induk dan elemen turunan tidak menyertakan properti tersebut sebagai bagian dari daftar anggota kelas. Salah satu skenario utama adalah mengaktifkan elemen turunan untuk memberi tahu elemen induk cara menyajikannya di UI. Misalnya, lihat Dock dan Left. Untuk informasi selengkapnya, lihat Gambaran umum properti terlampir.

Baca juga