Nilai default atribut dapat memastikan validitas atribut.
Validitas verifikasi atribut dapat digunakan untuk memverifikasi atribut masukan dan panggilan balik wajib atribut, yaitu pemberitahuan harus dilakukan terlepas dari apakah atribut telah berubah atau tidak.
Pemberitahuan perubahan atribut, ketika suatu atribut berubah, program dapat diberitahu untuk melakukan serangkaian proses.
Tidak ada yang salah dengan WPF disini, mari kita lihat bagaimana properti ketergantungan menyelesaikan masalah di atas.
Ringkasan konten mendefinisikan atribut ketergantungan yang pertama dan paling sederhana, nilai atribut ketergantungan, metadata atribut pembungkus atribut operasi dasar (PropertyMetadata)
Perilaku dasar metadata atribut
Meskipun kata-kata asli MSDN blak-blakan, namun keakuratannya tidak diragukan lagi, setelah Anda memahaminya, Anda akan mendapatkan pengalaman berbeda saat melihatnya.
1. Tentukan atribut ketergantungan yang pertama dan paling sederhana
Kata asli MSDN: Windows Presentation Foundation (WPF) menyediakan serangkaian layanan yang dapat digunakan untuk memperluas fungsionalitas properti runtime bahasa umum (CLR). Layanan ini sering secara kolektif disebut sebagai sistem properti WPF. Properti yang didukung oleh sistem properti WPF disebut properti ketergantungan.
Mari kita definisikan atribut Age dependency sebagai berikut:
DPC kelas publik CustomPeople
{
publik statis hanya baca DependencyProperty AgeProperty =
DependencyProperty.Register("Umur", typeof(int), typeof(DPCustomPeople));
kekosongan publik DisplayAgeProperty()
{
Console.WriteLine("DPName:" + DPCustomPeople.AgeProperty.Name);
Console.WriteLine("DPPropertyType:" + DPCustomPeople.AgeProperty.PropertyType);
Console.WriteLine("DPOWnerType:" + DPCustomPeople.AgeProperty.OwnerType);
}
}
Kemudian panggil hasil outputnya
Program kelas
{
kekosongan statis Utama (string[] args)
{
DPCustomPeople orang = DPCustomPeople baru();
orang.DisplayAgeProperty();
}
}
Anda mungkin belum familiar dengan kelas DependencyProperty. Kelas DependencyProperty menyediakan beberapa karakteristik dasar properti ketergantungan.
Cara untuk mendaftarkan properti ketergantungan adalah dengan memanggil metode Daftar statis dari DependencyProperty, yang menyediakan beberapa metode kelebihan beban, namun tiga langkah berikut diperlukan. Setelah pendaftaran selesai, itu adalah properti statis
Berikan nama terdaftar (Nama) "Umur"
Daftarkan tipe properti (PropertyType) typeof (int)
Daftarkan tipe pemilik atribut ketergantungan (OwnerType) typeof (DPCustomPeople)
Catatan: Nama atribut, tipe atribut, dan tipe pemilik atribut tidak dapat diubah setelah didaftarkan.
Berikut hasil keluarannya
2. Operasi dasar nilai atribut dependen (perolehan dan penugasan nilai)
Setelah mendefinisikan properti Age dependency, kita seharusnya dapat melakukan operasi perolehan nilai dan penugasan pada properti tersebut. DependencyProperty sendiri tidak menyediakan operasi ini, namun ditangani oleh DependencyObject.
DependencyObject mewakili objek yang berpartisipasi dalam sistem properti ketergantungan.
Oleh karena itu, kelas yang ditentukan harus mewarisi dari DependencyObject, lalu menulis ulang DPCustomPeople
kelas publik DPCustomPeople:System.Windows.DependencyObject
{
}
Operasi penetapan nilai dasar metode GetValue dan SetValue
kekosongan publik DPPropertyBasicOperator()
{
Console.WriteLine("Umur:" + ini.GetValue(DPCustomPeople.AgeProperty));
this.SetValue(DPCustomPeople.AgeProperty, 24);
Console.WriteLine("ChangedAge:" + this.GetValue(DPCustomPeople.AgeProperty));
}
Hasil keluaran
3. Pembungkus atribut menggunakan metode GetValue dan SetValue untuk mengoperasikan nilai, sehingga kita dapat menggabungkannya dan mendefinisikan atribut Age.
usia int publik
{
dapatkan { kembali (int)GetValue(AgeProperty);
set { SetValue(AgeProperty, nilai });
}
Catatan: Konvensi penamaan untuk kemasan properti dependen adalah menghilangkan Properti berikut
kekosongan publik DPPropertyBasicOperatorUsingProperty()
{
Console.WriteLine("Umur:" + ini.Umur);
ini.Umur=24;
Console.WriteLine("Umur Berubah:" + ini.Umur);
}
Apakah kode di atas terlihat lebih ringkas?
4. Metadata Properti (PropertyMetadata)
MSDN asli: Sistem properti Windows Presentation Foundation (WPF) mencakup sistem pelaporan metadata yang tidak terbatas pada apa yang dapat dilaporkan tentang properti melalui refleksi atau fitur runtime bahasa umum (CLR) reguler.
Berbicara tentang metadata atribut, hal pertama yang terlintas dalam pikiran adalah Atribut .net
Orang kelas publik
{
[Nilai Default(200),Kategori("Tata Letak")]
lebar int publik { dapatkan;
}
Atribut perlu menggunakan kekuatan Visual Studio untuk membuat dukungan ramah IDE untuk Atribut, atau mengandalkan refleksi untuk menetapkan nilai.
Namun tanpa teknologi ini, new akan membuat instance baru melalui saluran normal, dan penambahan Atribut tidak akan berpengaruh. Kami tidak dapat mengandalkan Atribut ini untuk memastikan beberapa karakteristik dasar dari atribut (seperti nilai default). atribut. Berbeda dari metadata yang dijelaskan di atas.
Metadata untuk properti ketergantungan
Dapat ditentukan secara unik oleh kelas di mana properti ketergantungan didefinisikan Dapat diubah ketika properti ketergantungan ditambahkan ke kelas lain Dapat secara eksplisit ditimpa oleh semua kelas turunan yang mewarisi properti ketergantungan dari kelas dasar yang menentukan. Bahasa di atas blak-blakan, tapi Tapi itu menjelaskan maksudnya. Tapi kita tidak selalu bisa memahami pemikiran desainernya pada saat pertama. Mari kita ketahui dulu keberadaan konsep ini.
5. Perilaku dasar metadata atribut Perilaku dasar metadata atribut menyediakan tiga fungsi untuk atribut dependen. Ini juga merupakan masalah yang baru saja diangkat dalam artikel ini.
Properti default properti notifikasi properti panggilan balik wajib Pertama-tama mari kita lihat konstruktor PropertyMetadata yang lengkap. Jika PropertyMetadata default tidak disetel untuk properti dependen, objek PropertyMetadata akan secara otomatis dibuat secara internal untuk properti dependen.
PropertyMetadata publik(objek defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback)
Atribut dependen meminjam konsep metadata atribut untuk melengkapi nilai default atribut, pemberitahuan atribut, panggilan balik paksa, dan perilaku lainnya
1.Atribut nilai default
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Nama", typeof(string), typeof(DPCustomPeople),
PropertyMetadata baru(string.Kosong));
Kebanyakan orang akan bertanya-tanya ketika melihat ini. Mengapa menggunakan PropertyMetadata untuk menetapkan nilai default? Mengapa tidak mendaftarkannya langsung di metode Daftar?
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Nama", typeof(string), typeof(DPCustomPeople),
string.Kosong);
Tentu saja, pertanyaan ini sudah lama ada pada saya, dan tidak ada yang bisa saya lakukan jika saya tidak bisa menyelesaikannya, jadi saya biarkan saja untuk saat ini.
Catatan: Saat menetapkan nilai default ke properti di PropertyMetadata, kebenaran jenis tidak dapat dideteksi.
Definisi seperti itu, karena nilai default segmen kode dp di vs adalah 0, ini adalah sesuatu yang perlu diperhatikan
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Nama", typeof(string), typeof(DPCustomPeople),
Metadata Properti UI baru(0));
2. Atribut operasi pemulihan nilai default
Setelah properti diberi nilai, Anda dapat mengembalikan nilai default melalui metode ClearValue dari DependencyObject, seperti yang ditunjukkan dalam kode berikut
Nama string publik
{
dapatkan { kembali (string)GetValue(NamaProperti);
set { SetValue(NamaProperti, nilai });
}
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Nama", typeof(string), typeof(DPCustomPeople),
new UIPropertyMetadata(string.Empty));
kekosongan publik DPPropertyClearOperator()
{
Console.WriteLine("Nama:" + ini.Nama);
ini.Nama="Terry";
Console.WriteLine("Nama yang Diubah:" + Nama.ini);
this.ClearValue(NamaProperti);
Console.WriteLine("Nama:" + ini.Nama);
}
Hasil keluaran
Catatan: Bedakan antara penetapan default dan nilai default
Penetapan default biasanya dilakukan di konstruktor, tetapi ini bukan nilai default (ini berlaku sebelum munculnya properti ketergantungan), terutama ketika kelas turunan menimpa properti.
Siswa kelas publik : DPCustomPeople
{
Siswa Publik()
{
this.Name = "Langit";
}
kekosongan publik TestSubDefaultDpValue()
{
Console.WriteLine("Hapus Sebelumnya:"+ini.Nama);
this.ClearValue(Student.NameProperty);
Console.WriteLine("Hapus Setelah:" + this.Name);
}
}
Hasil keluaran
3.Pemberitahuan perubahan properti
Fungsi ini adalah yang paling umum digunakan. Ketika nilai properti berubah, callback PropertyChangedCallback dipicu.
bool publik IsBoy
{
dapatkan { kembali (bool)GetValue(IsBoyProperty);
set { SetValue(IsBoyProperty, nilai });
}
publik statis hanya baca DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", typeof(bool), typeof(Siswa),
UIPropertyMetadata baru(salah, PropertyChangedCallback baru(IsBoyPropertyChangedCallback)));
kekosongan statis publik IsBoyPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Siswa st = d sebagai Siswa;
jika (st.IsBoy)
{
Console.WriteLine("Halo,Nak");
}
kalau tidak
{
Console.WriteLine("Halo,Gadis");
}
}
kekosongan publik TestPropertyChangedCallback()
{
ini.IsBoy = salah;
ini.IsBoy = benar; ini.IsBoy = benar;
}
Anda dapat melihat hasil keluaran nilai lama dan nilai baru melalui DependencyPropertyChangedEventArgs
Catatan:
(1). Melalui hasil keluaran di atas, pernahkah Anda melihat bahwa nilai default properti dependen tidak akan memicu notifikasi perubahan properti?
(2). Memicu pemberitahuan perubahan atribut secara manual
Jika Anda ingin nilai default memicu perubahan properti (pada kenyataannya, terkadang hal ini sangat diperlukan), Anda tidak perlu menunggu dan memicunya secara manual.
kekosongan pribadi RaiseIsBoyPropertyChangedCallback()
{
IsBoyPropertyChangedCallback(ini, DependencyPropertyChangedEventArgs baru
(Student.IsBoyProperty, Student.IsBoyProperty.DefaultMetadata.DefaultValue, null));
}
(3) Ketika ada pemberitahuan perubahan atribut, pastikan untuk memastikan kebenaran jenis nilai default atribut.
Kita tahu bahwa tipe nilai memiliki nilai default, tetapi tipe referensi tidak (yaitu, tipe tersebut dapat ditetapkan ke null). Apakah suatu tipe memiliki tipe default dapat diperiksa menggunakan kata kunci default. Seperti yang ditunjukkan di bawah ini
Kami menulis ulang nilai default properti ketergantungan yang ditentukan di atas menjadi nol. Ini dapat berjalan dengan baik ketika tidak ada PropertyChangedCallback, tetapi ketika ada pemberitahuan perubahan properti, bencana terjadi, dan program akan mengeluarkan pengecualian, mengatakan bahwa tipenya tidak. cocok.
publik statis hanya baca DependencyProperty IsBoyProperty =
DependencyProperty.Register("IsBoy", typeof(bool), typeof(Siswa),
UIPropertyMetadata baru(null, PropertyChangedCallback baru(IsBoyPropertyChangedCallback)));
Mari kita lihat kembali tipe referensinya. Jika nilai defaultnya adalah null, semuanya akan baik-baik saja.
IList publik LovedGirl
{
dapatkan { kembali (IList)GetValue(LovedGirlProperty);
set { SetValue(LovedGirlProperty, nilai });
}
publik statis hanya baca DependencyProperty LovedGirlProperty =
DependencyProperty.Register("LovedGirl", typeof(IList), typeof(Siswa),
UIPropertyMetadata baru(null, PropertyChangedCallback baru(LovedGirlChangedCallback)));
kekosongan statis publik LovedGirlChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Siswa st = d sebagai Siswa;
foreach (item var di e.NewValue sebagai IList)
{
Konsol.WriteLine(item);
}
}
kekosongan publik TestReferenceDpType()
{
Daftar<string> daftar = Daftar baru<string>();
daftar.Tambahkan("gadis 1");
daftar.Tambahkan("gadis 2");
this.LovedGirl = daftar;
}
4. Panggilan balik atribut paksa
Pertama-tama, nilai default masih tidak memicu metode panggilan balik.
Metode panggilan balik paksa berarti bahwa terlepas dari apakah nilai atribut berubah atau tidak, metode panggilan balik akan dimasukkan.
Skor int publik
{
dapatkan { kembali (int)GetValue(ScoreProperty);
set { SetValue(ScoreProperty, nilai });
}
DependencyProperty ScoreProperty =
DependencyProperty.Register("Skor", typeof(int), typeof(Siswa),
UIPropertyMetadata baru(0,null,CoerceValueCallback baru(ScoreCoerceValueCallback)));
objek statis publik ScoreCoerceValueCallback(DependencyObject d, objek baseValue)
{
Konsol.WriteLine(baseValue);
kembalikan nilai dasar;
}
kekosongan publik TestCoerceValueCallback()
{
ini.Skor = 0;
ini.Skor = 0;
ini.Skor = 0;
}