Bagikan melalui


Properti pemuatan dan dependensi XAML (WPF .NET)

Implementasi Windows Presentation Foundation (WPF) dari prosesor Extensible Application Markup Language (XAML) secara inheren menyadari properti dependensi. Dengan demikian, prosesor XAML menggunakan metode sistem properti WPF untuk memuat XAML dan memproses atribut properti dependensi, dan sepenuhnya melewati pembungkus properti dependensi dengan menggunakan metode sistem properti WPF seperti GetValue dan SetValue. Jadi, jika Anda menambahkan logika kustom ke pembungkus properti properti dependensi kustom Anda, logika tersebut tidak akan dipanggil oleh prosesor XAML saat nilai properti diatur dalam XAML.

Penting

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

Prasyarat

Artikel ini mengasumsikan pengetahuan dasar tentang properti dependensi, dan bahwa Anda telah membaca gambaran umum properti Dependensi. Untuk mengikuti contoh dalam artikel ini, ini membantu jika Anda terbiasa dengan Extensible Application Markup Language (XAML) dan tahu cara menulis aplikasi WPF.

Performa pemuat WPF XAML

Secara komputasi lebih murah bagi prosesor WPF XAML untuk langsung memanggil SetValue untuk mengatur nilai properti dependensi, daripada menggunakan pembungkus properti properti dependensi.

Jika prosesor XAML memang menggunakan pembungkus properti, itu akan mengharuskan menyimpulkan seluruh model objek kode pencadangan hanya berdasarkan jenis dan hubungan anggota yang ditunjukkan dalam markup. Meskipun jenis dapat diidentifikasi dari markup dengan menggunakan kombinasi xmlns atribut rakitan dan , mengidentifikasi anggota, menentukan anggota mana yang dapat ditetapkan sebagai atribut, dan menyelesaikan jenis nilai properti yang didukung, akan memerlukan refleksi ekstensif menggunakan PropertyInfo.

Sistem properti WPF mempertahankan tabel penyimpanan properti dependensi yang diterapkan pada jenis turunan tertentu DependencyObject . Prosesor XAML menggunakan tabel tersebut untuk menyimpulkan pengidentifikasi properti dependensi untuk properti dependensi. Misalnya, menurut konvensi pengidentifikasi properti dependensi untuk properti dependensi bernama ABC .ABCProperty Prosesor XAML dapat secara efisien mengatur nilai properti dependensi apa pun dengan memanggil SetValue metode pada jenis yang berisi menggunakan pengidentifikasi properti dependensi.

Untuk informasi selengkapnya tentang pembungkus properti dependensi, lihat Properti dependensi kustom.

Implikasi untuk properti dependensi kustom

Prosesor WPF XAML melewati pembungkus properti dan langsung memanggil SetValue untuk mengatur nilai properti dependensi. Jadi, hindari menempatkan logika tambahan di set aksesor properti dependensi kustom Anda karena logika tersebut tidak akan berjalan saat nilai properti diatur dalam XAML. Aksesor set hanya boleh berisi SetValue panggilan.

Demikian pula, aspek prosesor WPF XAML yang mendapatkan nilai properti melewati pembungkus properti dan langsung memanggil GetValue. Jadi, hindari juga menempatkan logika tambahan di get aksesor properti dependensi kustom Anda karena logika tersebut tidak akan berjalan saat nilai properti dibaca di XAML. Aksesor get hanya boleh berisi GetValue panggilan.

Properti dependensi dengan contoh pembungkus

Contoh berikut menunjukkan definisi properti dependensi yang direkomendasikan dengan pembungkus properti. Pengidentifikasi properti dependensi disimpan sebagai public static readonly bidang, dan get aksesor dan set tidak berisi kode di luar metode sistem properti WPF yang diperlukan yang mendukung nilai properti dependensi. Jika Anda memiliki kode yang perlu dijalankan saat nilai properti dependensi Anda berubah, pertimbangkan untuk memasukkan kode tersebut ke PropertyChangedCallback properti dependensi Anda. Untuk informasi selengkapnya, lihat Panggilan balik yang diubah properti.

// Register a dependency property with the specified property name,
// property type, owner type, and property metadata. Store the dependency
// property identifier as a public static readonly member of the class.
public static readonly DependencyProperty AquariumGraphicProperty =
    DependencyProperty.Register(
      name: "AquariumGraphic",
      propertyType: typeof(Uri),
      ownerType: typeof(Aquarium),
      typeMetadata: new FrameworkPropertyMetadata(
          defaultValue: new Uri("http://www.contoso.com/aquarium-graphic.jpg"),
          flags: FrameworkPropertyMetadataOptions.AffectsRender,
          propertyChangedCallback: new PropertyChangedCallback(OnUriChanged))
    );

// Property wrapper with get & set accessors.
public Uri AquariumGraphic
{
    get => (Uri)GetValue(AquariumGraphicProperty);
    set => SetValue(AquariumGraphicProperty, value);
}

// Property-changed callback.
private static void OnUriChanged(DependencyObject dependencyObject, 
    DependencyPropertyChangedEventArgs e)
{
    // Some custom logic that runs on effective property value change.
    Uri newValue = (Uri)dependencyObject.GetValue(AquariumGraphicProperty);
    Debug.WriteLine($"OnUriChanged: {newValue}");
}
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata. Store the dependency
' property identifier as a public static readonly member of the class.
Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty =
    DependencyProperty.Register(
        name:="AquariumGraphic",
        propertyType:=GetType(Uri),
        ownerType:=GetType(Aquarium),
        typeMetadata:=New FrameworkPropertyMetadata(
            defaultValue:=New Uri("http://www.contoso.com/aquarium-graphic.jpg"),
            flags:=FrameworkPropertyMetadataOptions.AffectsRender,
            propertyChangedCallback:=New PropertyChangedCallback(AddressOf OnUriChanged)))

' Property wrapper with get & set accessors.
Public Property AquariumGraphic As Uri
    Get
        Return CType(GetValue(AquariumGraphicProperty), Uri)
    End Get
    Set
        SetValue(AquariumGraphicProperty, Value)
    End Set
End Property

' Property-changed callback.
Private Shared Sub OnUriChanged(dependencyObject As DependencyObject,
                                e As DependencyPropertyChangedEventArgs)
    ' Some custom logic that runs on effective property value change.
    Dim newValue As Uri = CType(dependencyObject.GetValue(AquariumGraphicProperty), Uri)
    Debug.WriteLine($"OnUriChanged: {newValue}")
End Sub

Baca juga