Que fait InitializeComponent () et comment fonctionne-t-il dans WPF?

166

Que fait InitializeComponent()et comment ça marche dans WPF?

En général d'abord, mais je serais particulièrement intéressé de connaître les détails sanglants de l'ordre de construction, et ce qui se passe quand il y a des propriétés attachées.

Tim Lovell-Smith
la source
2
Merci, je pense que ce sont de très bonnes réponses ci-dessous! Personne n'a mentionné exactement les AttachedProperties, mais maintenant je sais que toutes les AttachedProperties dans Xaml sont simplement créées dans le cadre de l'analyse Xaml, donc elles ne méritent pas vraiment une mention spéciale.
Tim Lovell-Smith

Réponses:

157

L'appel à InitializeComponent()(qui est généralement appelé dans le constructeur par défaut d'au moins Windowet UserControl) est en fait un appel de méthode à la classe partielle du contrôle (plutôt qu'un appel à la hiérarchie d'objets comme je m'y attendais au départ).

Cette méthode localise un URI vers le XAML pour le Window/ UserControlqui est en cours de chargement et le transmet à la System.Windows.Application.LoadComponent()méthode statique. LoadComponent()charge le fichier XAML qui se trouve au niveau de l'URI passé et le convertit en une instance de l'objet spécifié par l'élément racine du fichier XAML.

Plus en détail, LoadComponentcrée une instance du XamlParser, et construit une arborescence du XAML. Chaque nœud est analysé par le XamlParser.ProcessXamlNode(). Cela est transmis à la BamlRecordWriterclasse. Quelque temps après cela, je me perds un peu dans la façon dont le BAML est converti en objets, mais cela peut suffire à vous aider sur le chemin de l'illumination.

Remarque: Il InitializeComponentest intéressant de noter que le est une méthode sur l' System.Windows.Markup.IComponentConnectorinterface, dont Window/ UserControlimplémente dans la classe générée partielle.

J'espère que cela t'aides!

Brad Leach
la source
@Brad, comment avez-vous trouvé dans quelle interface InitializeComponent est défini? L'aide F1 sur l'appel dans le fichier .xaml.cs conduit à «page introuvable» tandis que dans le fichier .g.cs ou .gics conduit à la classe Microsoft.SPOT.Emulator.EmulatorComponent. Je suis nouveau sur WPF. Cette méthode est-elle générée au moment de la construction?
Vimes
@ АртёмЦарионов Sans un appel à InitializeComponent dans le constructeur, le contrôle ne s'affichera pas ou ne sera pas utilisable dans le XAML dans lequel il se trouve.
Jason
Intéressant. J'avais l'impression que le xaml n'était utilisé que lors de la compilation. A quoi bon avoir le xaml disponible au moment de l'exécution et où est-il stocké?
Jesper Matthiesen
Pourquoi certaines méthodes me donnent-elles une "référence d'objet n'est pas définie sur une instance d'un objet". ?
Peter Gruppelaar
26

Regarder le code aide toujours aussi. Autrement dit, vous pouvez réellement jeter un œil à la classe partielle générée (qui appelle LoadComponent ) en procédant comme suit:

  1. Accédez au volet Explorateur de solutions dans la solution Visual Studio qui vous intéresse.
  2. Il y a un bouton dans la barre d'outils de l'Explorateur de solutions intitulé «Afficher tous les fichiers». Basculez ce bouton.
  3. Maintenant, développez le dossier obj , puis le dossier Debug ou Release (ou quelle que soit la configuration que vous construisez) et vous verrez un fichier intitulé YourClass .g.cs.

Les YourClass .g.cs ... est le code de produit classe partielle. Encore une fois, si vous ouvrez cela, vous pouvez voir la méthode InitializeComponent et comment elle appelle LoadComponent ... et bien plus encore.

cplotts
la source
12
Notez que vous pouvez le faire en une seule étape en cliquant avec le bouton droit de la souris sur l'appel de méthode dans le constructeur et en sélectionnant «Aller à la définition».
Brad Leach
2
Ah, c'est vrai ... j'ai oublié ça. Beaucoup plus facile de cette façon. Eh bien, au moins, vous savez comment il est inclus dans le projet. Sourire.
cplotts
1
@Brad Leach, Late to this party, you can do it with F12
Julius Depulla