Apa yang dilakukan oleh InitializeComponent (), dan bagaimana cara kerjanya di WPF?

166

Apa yang InitializeComponent()dilakukan, dan bagaimana cara kerjanya di WPF?

Secara umum pertama, tapi saya terutama akan tertarik untuk mengetahui detail berdarah dari urutan konstruksi, dan apa yang terjadi ketika ada Properti Terlampir.

Tim Lovell-Smith
sumber
2
Terima kasih, saya pikir ini adalah jawaban yang cukup bagus di bawah ini! Tidak ada yang menyebutkan AttachedProperties secara tepat, tapi sekarang saya tahu bahwa AttachedProperties di Xaml baru saja dibuat sebagai bagian dari penguraian Xaml, jadi mereka tidak benar-benar layak disebutkan secara khusus.
Tim Lovell-Smith

Jawaban:

157

Panggilan ke InitializeComponent()(yang biasanya dipanggil dalam konstruktor default setidaknya Windowdan UserControl) sebenarnya adalah pemanggilan metode ke kelas parsial dari kontrol (daripada memanggil hierarki objek seperti yang saya harapkan pertama kali).

Metode ini menempatkan URI ke XAML untuk Window/ UserControlyang memuat, dan meneruskannya ke System.Windows.Application.LoadComponent()metode statis. LoadComponent()memuat file XAML yang terletak di lulus dalam URI, dan mengubahnya menjadi turunan dari objek yang ditentukan oleh elemen root dari file XAML.

Secara lebih rinci, LoadComponentmembuat instance dari XamlParser, dan membangun pohon XAML. Setiap node diuraikan oleh XamlParser.ProcessXamlNode(). Ini diteruskan ke BamlRecordWriterkelas. Beberapa waktu setelah ini saya agak bingung bagaimana BAML dikonversi menjadi objek, tetapi ini mungkin cukup untuk membantu Anda di jalan menuju pencerahan.

Catatan: Menariknya, InitializeComponentini adalah metode pada System.Windows.Markup.IComponentConnectorantarmuka, yang diimplementasikan Window/ UserControldi kelas parsial yang dihasilkan.

Semoga ini membantu!

Brad Leach
sumber
@Brad, bagaimana Anda menemukan antarmuka InitializeComponent didefinisikan? Bantuan F1 pada panggilan dalam file .xaml.cs mengarah mengarah ke "halaman tidak ditemukan" saat dalam file .g.cs atau .gics mengarah ke kelas Microsoft.SPOT.Emulator.Emulator.EmulatorComponent. Saya baru mengenal WPF. Apakah metode ini dihasilkan pada waktu membangun?
Vimes
@ АртёмЦарионов Tanpa panggilan ke InitializeComponent di konstruktor, kontrol tidak akan ditampilkan atau dapat digunakan di XAML di mana ia berada.
Jason
Menarik. Saya mendapat kesan bahwa xaml hanya digunakan selama kompilasi .. Apa gunanya agar xaml tersedia saat runtime dan di mana ia disimpan?
Jesper Matthiesen
Mengapa beberapa metode memberi saya "referensi objek tidak disetel pada instance objek." ?
Peter Gruppelaar
26

Melihat kode juga selalu membantu. Artinya, Anda dapat melihat kelas parsial yang dihasilkan (yang memanggil LoadComponent ) dengan melakukan hal berikut:

  1. Buka panel Solution Explorer di solusi Visual Studio yang Anda minati.
  2. Ada tombol di bilah alat Solution Explorer berjudul 'Tampilkan Semua File'. Matikan tombol itu.
  3. Sekarang, memperluas obj folder dan kemudian Debug atau Rilis folder (atau konfigurasi Anda sedang membangun apa pun) dan Anda akan melihat sebuah file berjudul YourClass .g.cs.

The YourClass .g.cs ... adalah kode untuk kelas parsial yang dihasilkan. Sekali lagi, jika Anda membukanya, Anda dapat melihat metode InitializeComponent dan bagaimana ia memanggil LoadComponent ... dan banyak lagi.

cplotts
sumber
12
Perhatikan bahwa Anda dapat melakukan ini dalam satu langkah dengan mengklik kanan pemanggilan metode di konstruktor dan memilih "Pergi ke Definisi".
Brad Leach
2
Ah, benar ... lupa tentang itu. Jauh lebih mudah seperti itu. Yah, setidaknya Anda tahu bagaimana itu dimasukkan dalam proyek. Menyeringai.
cplotts
1
@Brad Leach, Terlambat ke pesta ini, Anda bisa melakukannya dengan F12
Julius Depulla