winforms - Winforms Designer 如何实例化我的表单?

标签 winforms visual-studio-2008 designer windows-forms-designer

我正在开发自己的 WinForms 设计器。它必须能够加载现有的自定义表单类型。我遇到的问题之一是没有默认构造函数的表单:我的代码当前会实例化表单,然后才能将其加载到设计器中,这需要默认构造函数。

OTOH,VS2008能够加载此类表单。我相信它实际上并没有实例化我的表单(如 this question 中所述):即使默认的构造函数也不会被执行。并且它并没有真正执行InitializeComponent()。我刚刚在该函数中添加了一个消息框,但它没有显示。

看起来它动态地模仿自定义表单类型,并且仅执行 InitializeComponent 中它认为相关的部分代码。

有谁知道我在哪里可以找到有关 VS 设计器如何工作的更多信息。

TIA。

注意:我发现了这个related question没有令人满意的答案

编辑:附加信息:Steve 向我推荐了 CodeDom,这非常有趣。但我的问题是,我需要加载到设计器中的类型已经编译,而不是作为源代码提供。我找不到任何方法将 CodeDom 反序列化应用于编译的代码。

最佳答案

找到这个here :

When you open a new Windows Application project in VS, you see an empty form called Form1 in design view. Now, you haven't built the project yet, so how is the designer able to create an instance of Form1 and show it? Well, the designer is not really instantiating Form1 at all. It is creating an instance of the base class of Form1, i.e., System.Windows.Forms.Form. With a basic knowledge of object oriented programming, you will find that this intuitively makes sense. When you are designing Form1, you start with the base class, Form, and customize it. This is exactly what the designer helps you to do.

Now let's say you added a bunch of controls to the Form and closed the designer. When you reopen the designer, the controls are still there. However, the base class Form doesn't have these controls on it, so if the designer isn't running the constructor of Form1, how did it show the controls? The designer does this by deserializing the code in InitializeComponent. Each language that the designer supports has a CodeDomProvider that is responsible for providing a parser that parses the code in InitializeComponent and creates a CodeDom representation of it. The designer then invokes a set of CodeDomSerializers to deserialize this into actual Controls (or more broadly, Components) that it can add to the design time Form. Now, I have glossed over a lot of details in that description, but the point here is that Form1's constructor and InitializeComponent are never really invoked. Instead, the designer parses the statements in InitializeComponent to figure out what controls to instantiate and add to the form.

<小时/>

以上是 Visual Studio 中的 Windows 窗体设计器如何加载窗体。如果您正在寻找一种方法来创建没有默认构造函数的表单实例并且仍然可以访问所包含的组件/控件,那么我不知道有什么解决方案。我所知道的唯一允许您绕过缺少默认构造函数的方法是 FormatterServices.GetUninitializedObject ,但要小心...

Because the new instance of the object is initialized to zero and no constructors are run, the object might not represent a state that is regarded as valid by that object.

我也有一个需要实例化编译表单的应用程序,但一直使用 Activator.CreateInstance并要求其他开发人员如果希望在我的应用程序中访问其表单,则至少要包含一个私有(private)默认构造函数。由于我们拥有整个代码库并且每个人都知道这一要求,因此这不是问题并且对我们来说效果很好。

关于winforms - Winforms Designer 如何实例化我的表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/872536/

相关文章:

c# 表单最小化/最大化按钮不见了?

.net - 在 VB.NET 中向 DataGridView 添加行

visual-studio-2008 - 来自 Mac 的远程桌面上的 Visual Studio - 有什么问题吗?

c++ - qt 4.5.0 与 Visual Studio 2008 的集成有什么问题?

.net - 如何让winform窗口透明且图片可见?

c++ - 在非 winforms 应用程序中创建表单

c# - 使用 XML 序列化将属性放入不同的 XML 命名空间

visual-studio - XAML : How to change background color only in Design mode?

.net - Windows 窗体控件设计器,添加 'task menus'

c# - 为什么 WinForms 设计器中的控件会自行调整大小?