4

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

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

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

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

TIA.

Примечание: Я нашел это related question без убедительные ответы

EDIT: Дополнительная информация: Стив указывает мне CodeDom, что очень insteresting. Моя проблема заключается в том, что типы, которые мне нужно загрузить в мой дизайнер, уже скомпилированы вместо того, чтобы быть доступными в качестве исходного кода. Я не могу найти способ применить десериализацию CodeDom к скомпилированному коду.

+1

Возможно, вам удастся настроить существующие элементы дизайна Windows Forms, а не изобретать их повторно. Они обрабатывают всевозможные сценарии, о которых вы не будете думать, пока ваши пользователи не пожалуются на их недостаток. –

+1

Джон, это точно моя точка. Где вы видите, что я изобретаю что-нибудь? –

ответ

12

Нашел here:

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

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


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

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

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

+0

Стив, очень интересная ссылка. Благодаря! Это в значительной степени подтверждает общий механизм, который я себе представлял, но я не знал о CodeDom. Погрузитесь в него сразу ;-) –

+0

CodeDoms, похоже, заводит меня в тупик при попытке загрузить * скомпилированные * настраиваемые типы форм :-( –

+0

«никаких конструкторов не запускаются» - на соответствующую заметку это не применяется для 'UserControl', если я помещаю бесконечный цикл в конструктор 'UserControl' и пытаюсь перетащить его в форму, он блокирует визуальную студию. Также есть несколько других исключений, упомянутых в комментариях к связанная страница блога msdn. – jrh

0

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

Смежные вопросы