Как конструктор Winforms создает мою форму?

Я разрабатываю свой собственный дизайнер WinForms. Он должен иметь возможность загружать существующие типы настраиваемых форм. Одна из проблем, с которыми я столкнулся, - это формы без ctor по умолчанию: мой код в настоящее время создает экземпляр формы, прежде чем он сможет загрузить ее в конструктор, для чего требуется ctor по умолчанию.

OTOH, VS2008 умеет загружать такие формы. Я считаю, что он на самом деле не создает экземпляр моей формы (как указано в этом вопросе): даже ctors по умолчанию не выполняются. И он действительно не выполняет InitializeComponent (). Я только что добавил в эту функцию окно сообщения, и оно не отображается.

Похоже, он динамически имитирует тип настраиваемой формы и выполняет только те части кода в InitializeComponent, которые он считает актуальными.

Кто-нибудь знает, где я могу найти дополнительную информацию о том, как работает конструктор VS.

TIA.

Примечание. Я нашел этот связанный вопрос, но без удовлетворительных ответов

РЕДАКТИРОВАТЬ: Дополнительная информация: Стив указывает мне на CodeDom, что очень интересно. Однако моя проблема в том, что типы, которые мне нужно загрузить в мой дизайнер, уже скомпилированы, а не доступны в виде исходного кода. Я не могу найти способ применить десериализацию CodeDom к скомпилированному коду.


person Serge Wautier    schedule 16.05.2009    source источник
comment
Возможно, вам больше повезет настроить существующие элементы дизайна Windows Forms, а не изобретать их заново. Они обрабатывают всевозможные сценарии, о которых вы не будете думать, пока ваши пользователи не пожалуются на их отсутствие.   -  person John Saunders    schedule 18.05.2009
comment
Джон, это именно моя точка зрения. Где вы видите, что я что-то изобретаю заново?   -  person Serge Wautier    schedule 18.05.2009


Ответы (2)


Нашел это здесь:

Когда вы открываете новый проект приложения Windows в VS, вы видите пустую форму с именем Form1 в режиме конструктора. Итак, вы еще не создали проект, так как же дизайнер может создать экземпляр Form1 и показать его? Что ж, на самом деле дизайнер вообще не создает экземпляр Form1. Он создает экземпляр базового класса Form1, то есть System.Windows.Forms.Form. Обладая базовыми знаниями объектно-ориентированного программирования, вы обнаружите, что это интуитивно понятно. При разработке Form1 вы начинаете с базового класса Form и настраиваете его. Именно в этом вам помогает дизайнер.

Теперь предположим, что вы добавили несколько элементов управления в форму и закрыли дизайнер. Когда вы снова открываете конструктор, элементы управления все еще там. Однако базовый класс Form не имеет этих элементов управления, поэтому, если дизайнер не запускает конструктор Form1, как он отображает элементы управления? Дизайнер делает это путем десериализации кода в InitializeComponent. Каждый язык, поддерживаемый дизайнером, имеет CodeDomProvider, который отвечает за предоставление синтаксического анализатора, который анализирует код в InitializeComponent и создает его представление CodeDom. Затем дизайнер вызывает набор CodeDomSerializer для десериализации в фактические элементы управления (или, шире, в компоненты), которые он может добавить в форму времени разработки. Я замалчил многие детали в этом описании, но дело в том, что конструктор Form1 и InitializeComponent никогда не вызываются. Вместо этого дизайнер анализирует операторы в InitializeComponent, чтобы выяснить, какие элементы управления создать и добавить в форму.


Выше показано, как дизайнер Windows Forms в Visual Studio загружает форму. Если вы ищете способ создать экземпляр формы, у которого нет конструктора по умолчанию и все еще есть доступ к содержащимся в нем компонентам / элементам управления, я не знаю решения. Единственный известный мне метод, позволяющий обойти отсутствие конструктора по умолчанию, - это FormatterServices.GetUninitializedObject, но будьте осторожны ...

Поскольку новый экземпляр объекта инициализируется нулем и конструкторы не запускаются, объект может не представлять состояние, которое этот объект считает допустимым.

У меня тоже есть приложение, которое требует создания экземпляров скомпилированных форм, но всегда использовало Activator .CreateInstance и требовал от других разработчиков включения, по крайней мере, частного конструктора по умолчанию, если они хотят, чтобы их форма была доступна в моем приложении. Поскольку мы владеем всей кодовой базой, и все знают об этом требовании, это не проблема и хорошо работает для нас.

person Steve Dignan    schedule 16.05.2009
comment
Стив, очень интересная ссылка. Спасибо! Это в значительной степени подтверждает общий механизм, который я себе представлял, но я не знал о CodeDom. Сразу погрузимся в это ;-) - person Serge Wautier; 16.05.2009
comment
CodeDoms, кажется, завели меня в тупик при попытке загрузить скомпилированные типы пользовательских форм :-( - person Serge Wautier; 17.05.2009
comment
никакие конструкторы не запускаются - в соответствующей заметке это не относится к UserControls, если я помещаю бесконечный цикл в конструктор UserControl и пытаюсь перетащить его в форму, он блокирует визуальную студию. Есть также пара других исключений из этого, упомянутых в комментариях на связанной странице блога msdn. - person jrh; 03.03.2017

В дополнение к ответу Стива, если вы добавите новую форму Windows в проект, но сделаете ее абстрактной, вы все равно сможете открыть ее в дизайнере. Однако, если вы добавляете другую форму и производите ее от первой (абстрактной) формы, вы получите ошибку при попытке открыть форму в конструкторе.

person Andy    schedule 16.05.2009