Winforms Designer 如何实例化我的表单? [英] How does the Winforms Designer instantiate my form?

查看:22
本文介绍了Winforms Designer 如何实例化我的表单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发自己的 WinForms 设计器.它必须能够加载现有的自定义表单类型.我遇到的问题之一是没有默认 ctor 的表单:我的代码目前在将表单加载到设计器之前实例化表单,这需要默认 ctor.

I'm developing my own WinForms designer. It must be able to load existing custom form types. One of the issues I hit is forms without a default ctor: My code currently instantiates the form before it can load it into the designer, which requires a default ctor.

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

OTOH, VS2008 is able to load such forms. I believe it doesn't actually instantiate my form (as noted in this question): Even default ctors are not executed. And it doesn't truly execute InitializeComponent(). I just added a messagebox in that function and it doesn't show.

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

It looks like it dynamically mimic the custom form type and executes only parts of the code in InitializeComponent which it thinks is relevant.

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

Does anyone know where I can find more information regarding how the VS designer works.

TIA.

注意:我发现这个相关问题没有令人满意的答案

Note: I found this related question without satisfying answers

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

Additional info: Steve points me to CodeDom, which is very insteresting. My problem though is that the types I need to load into my designer are already compiled instead of being available as source code. I can't find any way to apply CodeDom deserialization to compiled code.

推荐答案

发现这个 此处:

当您打开一个新的 Windows 时VS中的应用项目,你看到一个设计中名为 Form1 的空表单看法.现在,你还没有建立项目还没有,设计师怎么样能够创建 Form1 的实例并展示它?嗯,设计师不是真正实例化 Form1.它正在创建基础的实例Form1 的类,即系统.Windows.Forms.Form.用一个面向对象的基础知识编程,你会发现这直觉上是有道理的.当你设计 Form1,您从基类,Form,并对其进行自定义.这正是设计师帮助你做.

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.

现在假设您添加了一堆控件到窗体并关闭设计师.当您重新打开设计师,控件仍然那里.但是,基类 Form没有这些控件,所以如果设计师没有运行Form1 的构造函数,它是如何显示的控件?设计师这样做通过反序列化代码初始化组件.每种语言设计师支持的有一个负责的 CodeDomProvider提供一个解析器来解析InitializeComponent 中的代码和创建一个 CodeDom 表示它.然后设计者调用一组CodeDomSerializers 反序列化这个进入实际控制(或更广泛地说,组件),它可以添加到设计时表格.现在,我已经掩盖了在很多细节上描述,但这里的重点是Form1 的构造函数和InitializeComponent 从来都不是真的调用.相反,设计器解析InitializeComponent 中的语句找出控制什么实例化并添加到表单中.

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,但要注意...


The above is how Windows Forms designer in Visual Studio loads a form. If what you are looking for is a way to create an instance of a form that has no default constructor and still have access to the contained components/controls, I'm not aware of a solution. The only method I'm aware of that allows you to bypass the lack of a default constructor is FormatterServices.GetUninitializedObject, but beware ...

因为对象的新实例被初始化为零并且没有构造函数被运行,对象可能不代表被视为的状态对该对象有效.

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 并要求其他开发人员至少包括一个私有的默认构造函数,如果他们希望他们的表单可以在我的应用程序中访问.由于我们拥有整个代码库并且每个人都知道要求,因此这不是问题,对我们来说效果很好.

I too have an app that requires instantiating compiled forms but have always used Activator.CreateInstance and required other developers to include, at the very least, a private default constructor if they want their form accessible in my app. Since we own the entire codebase and everyone is aware of the requirement, this isn't a problem and works out well for us.

这篇关于Winforms Designer 如何实例化我的表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆