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 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.
It looks like it dynamically mimic the custom form type and executes only parts of the code in InitializeComponent which it thinks is relevant.
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
EDIT: 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.
Found this 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.
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.
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.
As an addition to Steve's answer, if you add a new Windows Form to a project, but make it abstract, you can still open it in the designer. However, if you add another form, and have it derive from the first (abstract) form, you get an error when attempting to open the form in the designer.