Что делает InitializeComponent () и как он работает в WPF?

166

Что делает InitializeComponent()и как это работает в WPF?

В общем, во-первых, но мне было бы особенно интересно узнать мрачные детали порядка строительства и что происходит, когда есть Attached Properties.

Тим Ловелл-Смит
источник
2
Спасибо, я думаю, что это довольно хорошие ответы ниже! Никто точно не упомянул AttachedProperties, но теперь я знаю, что любые AttachedProperties в Xaml просто создаются как часть синтаксического анализа Xaml, поэтому они не заслуживают особого упоминания.
Тим Ловелл-Смит

Ответы:

157

Вызов InitializeComponent()(который обычно вызывается в конструкторе по умолчанию, по крайней мере, Windowи UserControl) на самом деле является вызовом метода частичного класса элемента управления (а не вызовом иерархии объектов, как я впервые ожидал).

Этот метод находит URI для XAML для Window/, UserControlкоторый загружается, и передает его System.Windows.Application.LoadComponent()статическому методу. LoadComponent()загружает файл XAML, расположенный в переданном в URI, и преобразует его в экземпляр объекта, указанный корневым элементом файла XAML.

Более подробно, LoadComponentсоздает экземпляр XamlParserи создает дерево XAML. Каждый узел анализируется с помощью XamlParser.ProcessXamlNode(). Это передается в BamlRecordWriterкласс. Некоторое время спустя я немного теряюсь в том, как BAML преобразуется в объекты, но этого может быть достаточно, чтобы помочь вам на пути к просветлению.

Примечание: Интересно, что InitializeComponentэто метод System.Windows.Markup.IComponentConnectorинтерфейса, который Window/ UserControlреализован в частично сгенерированном классе.

Надеюсь это поможет!

Брэд Лич
источник
@Brad, как вы узнали, какой интерфейс InitializeComponent определен в? Справка F1 по вызову в файле .xaml.cs приводит к «странице не найдена», а в файле .g.cs или .gics - к классу Microsoft.SPOT.Emulator.EmulatorComponent. Я новичок в WPF. Этот метод генерируется во время сборки?
Vimes
@ АртёмЦарионов Без вызова InitializeComponent в конструкторе элемент управления не будет отображаться или использоваться в XAML, в котором он находится.
Джейсон
Интересный. У меня сложилось впечатление, что xaml использовался только во время компиляции. Какой смысл иметь xaml во время выполнения и где он хранится?
Джеспер Маттисен
Почему некоторые методы дают мне «ссылка на объект не установлена ​​для экземпляра объекта». ?
Питер Группелаар
26

Просмотр кода всегда тоже помогает. То есть вы можете взглянуть на сгенерированный частичный класс (который вызывает LoadComponent ), выполнив следующие действия:

  1. Перейдите на панель обозревателя решений интересующего вас решения Visual Studio.
  2. На панели инструментов обозревателя решений есть кнопка «Показать все файлы». Переключить эту кнопку.
  3. Теперь разверните папку obj, а затем папку Debug или Release (или любую конфигурацию, которую вы создаете), и вы увидите файл с названием YourClass .g.cs.

В YourClass .g.cs ... код для сгенерированного частичного класса. Опять же, если вы откроете это, вы увидите метод InitializeComponent и то, как он вызывает LoadComponent ... и многое другое.

cplotts
источник
12
Обратите внимание, что вы можете сделать это за один шаг, щелкнув правой кнопкой мыши вызов метода в конструкторе и выбрав «Перейти к определению».
Брэд Лич
2
Ах, это верно ... забыл об этом. Намного проще. Ну, по крайней мере, вы знаете, как это входит в проект. Гринь.
cplotts
1
@Brad Leach, поздно на эту вечеринку, вы можете сделать это с F12
Юлиус Депулла