I've recently noticed some behaviour with the Visual Studio Designer (C#) that I don't understand and was wondering if someone could clarify...
One some of my Windows Forms, the first line of the designer generated code reads;
this.components = new System.ComponentModel.Container();
When this is the case, the dispose method, in that same designer file, the dispose method places two "Dispose" calls within the case "if" condition as follows;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
base.Dispose(disposing);
}
}
i.e. Nothing is called unless disposing is true, AND components is not null.
On some other forms, that first line in the designer generated code is missing. In these cases the base.Dispose call is outside the "if" condition as such...
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
I have noticed this while tracking down a bug with a form not closing, where this.components was null, yet the base.Dispose call was inside that condition (I suspect the designer code had been tampered with but that's another story.
What controls this behaviour?
(Some earlier forms in the project were created in VS 2005 and we now use VS 2008 - clue?)
This is reproducible behavior. When you create a new form, it starts out with a skeleton that includes the this.components constructor call. When you then add a component (say a Timer) and remove it again, the designer regenerates the code, now without the constructor call. That isn't a bug.
Fwiw, the skeleton code is generated by Common7\IDE\ItemTemplates\CSharp\Windows Forms\1033\Form.zip\form.designer.cs
Seeing the base.Dispose() call inside the if() statement is a bug. That might be self-induced. Or it might be a beta version of the skeleton code. VS2005 does it right. Do check the ItemsTemplatesCache folder.
6 years later and this problem still occurs. I've managed to track down at least one cause for it happening.
When testing if your component has a constructor that takes an IContainer, System.ComponentModel.Design.Serialization.ComponentCodeDomSerializer caches a reference to the Type of IContainer for your project. If you then save an object for another project within the same solution, or perhaps when you have made some other types of changes in your project, ComponentCodeDomSerializer can no longer find the constructor as the Type of IContainer is no longer equal to it's cached Type.
If this is happening lots for your project, there is a very ugly workaround. Add this VB or C# VisualStudioWorkaroundSerializer
class to your solution. Then add the attribute DesignerSerializer(GetType(VisualStudioWorkaroundSerializer), GetType(CodeDomSerializer))
to your component. Whenever your component is saved, this custom serializer will detect the problem, fix it, and force you to save again whenever this issue is about to occur.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With