Co robi InitializeComponent () i jak to działa w WPF?

166

Co robi InitializeComponent()i jak to działa w WPF?

Ogólnie rzecz biorąc, najpierw, ale szczególnie chciałbym poznać krwawe szczegóły kolejności budowy i co się dzieje, gdy są dołączone właściwości.

Tim Lovell-Smith
źródło
2
Dzięki, myślę, że poniżej są całkiem dobre odpowiedzi! Nikt nie wspomniał dokładnie o AttachedProperties, ale teraz wiem, że wszelkie AttachedProperties w Xaml są tworzone w ramach analizy Xaml, więc tak naprawdę nie zasługują na specjalną wzmiankę.
Tim Lovell-Smith

Odpowiedzi:

157

Wywołanie InitializeComponent()(które jest zwykle wywoływane w domyślnym konstruktorze co najmniej Windowi UserControl) jest w rzeczywistości wywołaniem metody do częściowej klasy kontrolki (a nie wywołaniem hierarchii obiektów, jak się spodziewałem).

Ta metoda lokalizuje identyfikator URI do kodu XAML dla Window/, UserControlktóry jest ładowany, i przekazuje go do System.Windows.Application.LoadComponent()metody statycznej. LoadComponent()ładuje plik XAML, który znajduje się w przekazanym identyfikatorze URI, i konwertuje go na wystąpienie obiektu, który jest określony przez element główny pliku XAML.

Bardziej szczegółowo LoadComponenttworzy wystąpienie XamlParseri kompiluje drzewo XAML. Każdy węzeł jest analizowany przez XamlParser.ProcessXamlNode(). To jest przekazywane BamlRecordWriterklasie. Po jakimś czasie trochę zagubiłem się w tym, jak BAML przekształca się w obiekty, ale to może wystarczyć, aby pomóc ci na ścieżce do oświecenia.

Uwaga: Co ciekawe, InitializeComponentjest to metoda System.Windows.Markup.IComponentConnectorinterfejsu, której Window/ UserControlimplementuje się w częściowo wygenerowanej klasie.

Mam nadzieję że to pomoże!

Brad Leach
źródło
@Brad, jak znalazłeś, w którym interfejsie jest zdefiniowany InitializeComponent? Pomoc F1 dotycząca wywołania w pliku .xaml.cs prowadzi do „nie znaleziono strony”, podczas gdy w pliku .g.cs lub .gics prowadzi do klasy Microsoft.SPOT.Emulator.EmulatorComponent. Jestem nowy w WPF. Czy ta metoda jest generowana w czasie kompilacji?
Vimes
@ АртёмЦарионов Bez wywołania InitializeComponent w konstruktorze formant nie będzie wyświetlany ani nie będzie można go używać w XAML, w którym się znajduje.
Jason
Ciekawy. Odniosłem wrażenie, że xaml był używany tylko podczas kompilacji. Po co mieć xaml w czasie wykonywania i gdzie jest przechowywany?
Jesper Matthiesen
Dlaczego niektóre metody podają mi informację „odwołanie do obiektu nie jest ustawione w instancji obiektu”. ?
Peter Gruppelaar
26

Spojrzenie na kod też zawsze pomaga. Oznacza to, że możesz faktycznie przyjrzeć się wygenerowanej klasie częściowej (która wywołuje LoadComponent ), wykonując następujące czynności:

  1. Przejdź do okienka Eksplorator rozwiązań w interesującym Cię rozwiązaniu programu Visual Studio.
  2. Na pasku narzędzi Eksploratora rozwiązań znajduje się przycisk zatytułowany „Pokaż wszystkie pliki”. Przełącz ten przycisk.
  3. Teraz rozwiń obj folder, a następnie Debug lub Release folder (lub cokolwiek konfiguracja jesteś budynku) i pojawi się plik o nazwie YourClass .g.cs.

W YourClass .g.cs ... jest kodem wygenerowanym częściowej klasy. Ponownie, jeśli to otworzysz, możesz zobaczyć metodę InitializeComponent i jak wywołuje ona LoadComponent ... i wiele więcej.

cplotts
źródło
12
Zauważ, że możesz to zrobić w jednym kroku, klikając prawym przyciskiem wywołanie metody w konstruktorze i wybierając „Przejdź do definicji”.
Brad Leach
2
Ach, zgadza się ... zapomniałem o tym. W ten sposób dużo łatwiej. Cóż, przynajmniej wiesz, jak jest to uwzględnione w projekcie. Szeroki uśmiech.
cplotts
1
@Brad Leach, Spóźniony na imprezę, możesz to zrobić z F12
Julius Depulla