Discussion:
Need Help to modify designer output code
(too old to reply)
schneider
2008-04-07 04:26:26 UTC
Permalink
Hello,
I'm trying to figure out how to change the lines following " '*** ' of
designer code.
I think I need to hijack the root designer and control designer. Looking for
some examples and/or direction.

below is a sample Form changed by me, to what I would like it to look like.

Thanks,
Schneider


<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class FormCalculatorResistance
Inherits System.Windows.Forms.Form

'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

' *** Added line below here ***
Private m_ControlFactory As New SchneiderSoft.UIControls.FactoryControls

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()

' *** Change below here ***
'Me.DropDownBase1 = New SchneiderSoft.UIControls.DropDownBase
Me.DropDownBase1 = m_ControlFactory.CreateDropDown

CType(Me.DropDownBase1,
System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'DropDownBase1
'
Me.DropDownBase1.Bounds = New System.Drawing.Rectangle(22, 12, 204, 30)
Me.DropDownBase1.DropControl = Nothing
Me.DropDownBase1.LevelSupportSecurity.LevelRequired = 0
Me.DropDownBase1.LevelSupportSecurity.LevelRequiredLabel = "Modified"
Me.DropDownBase1.Name = "DropDownBase1"
Me.DropDownBase1.TabIndex = 0

' *** Change below here ***
'Me.Controls.Add(Me.DropDownBase1)
Me.Controls.Add(DirectCast(DropDownBase1, Windows.Forms.Control))

Me.Name = "FormCalculatorResistance"
Me.Text = "Form Calculator Resistance"
CType(Me.DropDownBase1,
System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)

End Sub

' *** Change below here ***
'Friend WithEvents DropDownBase1 As SchneiderSoft.UIControls.DropDownBase
Friend WithEvents DropDownBase1 As
SchneiderSoft.AbstractInterfaces.IDropDown

End Class
Linda Liu[MSFT]
2008-04-07 07:04:10 UTC
Permalink
Hi Schneider,

You need to implement a custom CodeDomSerializer to control the generation
of component initialization code for your custom control/component at
design time. And then associate your custom CodeDomSerializer
implementation with the type of your control/component using a
DesignerSerializerAttribute.

For more information on the CodeDomSerializer class and a sample, please
refer to the following MSDN document:
http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serial
ization.codedomserializer.aspx

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
eschneider
2008-04-07 15:05:03 UTC
Permalink
Yes, but I think I still need to intercept the Root serializer for the
Form/Panel?
Post by Linda Liu[MSFT]
Hi Schneider,
You need to implement a custom CodeDomSerializer to control the generation
of component initialization code for your custom control/component at
design time. And then associate your custom CodeDomSerializer
implementation with the type of your control/component using a
DesignerSerializerAttribute.
For more information on the CodeDomSerializer class and a sample, please
http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serial
ization.codedomserializer.aspx
Hope this helps.
If you have any question, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu[MSFT]
2008-04-10 09:15:07 UTC
Permalink
Hi Schneider,

Thank you for your prompt reply!

A custom CodeDomSerializer for a control can only control the generation of
the control initialization code, which don't contain the code that adds the
control to its parent's Controls collection, e.g. a form.

So I also think that we need to intercept the root serializer for the form.
Unfortunately, I haven't worked out how to do this. I am consulting this
issue in our internal discussion group. As soon as I get an answer, I will
get it back to you.

I appreciate your patience!

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
eschneider
2008-04-10 20:45:20 UTC
Permalink
Yes, thats what I'm looking for.

Thanks,
Schneider
Post by Linda Liu[MSFT]
Hi Schneider,
Thank you for your prompt reply!
A custom CodeDomSerializer for a control can only control the generation of
the control initialization code, which don't contain the code that adds the
control to its parent's Controls collection, e.g. a form.
So I also think that we need to intercept the root serializer for the form.
Unfortunately, I haven't worked out how to do this. I am consulting this
issue in our internal discussion group. As soon as I get an answer, I will
get it back to you.
I appreciate your patience!
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
This posting is provided "AS IS" with no warranties, and confers no rights.
eschneider
2008-04-14 17:40:36 UTC
Permalink
Any update on this?

Thanks,
Schneider
Post by eschneider
Yes, thats what I'm looking for.
Thanks,
Schneider
Post by Linda Liu[MSFT]
Hi Schneider,
Thank you for your prompt reply!
A custom CodeDomSerializer for a control can only control the generation of
the control initialization code, which don't contain the code that adds the
control to its parent's Controls collection, e.g. a form.
So I also think that we need to intercept the root serializer for the form.
Unfortunately, I haven't worked out how to do this. I am consulting this
issue in our internal discussion group. As soon as I get an answer, I will
get it back to you.
I appreciate your patience!
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu[MSFT]
2008-04-15 05:30:35 UTC
Permalink
Hi Schneider,

I got a reply from an expert in the WinForm design time field.

He said that to control the code generation of a root object like a form,
we need to derive from the TypeCodeDomSerializer class to implement the
code generation we like. Then add a DesignerSerializerAttribute to the form
with a second parameter of TypeCodeDomSerializer. For example:

[DesignerSerializer(typeof(MyTypeSerializer),
typeof(TypeCodeDomSerializer))]
public class MyCustomForm : Form {
}

class MyTypeSerializer:TypeCodeDomSerializer
{}

TypeCodeDomSerializer does most of what you want, so you can simply derive
from it. The one thing it doesn't know about is "InitializeComponent".
You would have to add support for that. The following is a sample:

internal class ComponentTypeCodeDomSerializer : TypeCodeDomSerializer {
private static object _initMethodKey = new object();
private const string _initMethodName = "InitializeComponent";
private static ComponentTypeCodeDomSerializer _default;

internal new static ComponentTypeCodeDomSerializer Default {
get {
if (_default == null) {
_default = new ComponentTypeCodeDomSerializer();
}

return _default;
}
}

/// <include file='doc\ComponentTypeCodeDomSerializer.uex'
path='docs/doc[@for="ComponentTypeCodeDomSerializer.GetInitializeMethod"]/*'
/>
/// <devdoc>
/// This method returns the method to emit all of the
initialization code to for the given member.
/// The default implementation returns an empty constructor.
/// </devdoc>
protected override CodeMemberMethod
GetInitializeMethod(IDesignerSerializationManager manager,
CodeTypeDeclaration typeDecl, object value) {
if (manager == null) {
throw new ArgumentNullException("manager");
}

if (typeDecl == null) {
throw new ArgumentNullException("typeDecl");
}

if (value == null) {
throw new ArgumentNullException("value");
}

CodeMemberMethod method = typeDecl.UserData[_initMethodKey] as
CodeMemberMethod;

if (method == null) {
method = new CodeMemberMethod();
method.Name = _initMethodName;
method.Attributes = MemberAttributes.Private;
typeDecl.UserData[_initMethodKey] = method;

// Now create a ctor that calls this method.
CodeConstructor ctor = new CodeConstructor();

ctor.Statements.Add(new CodeMethodInvokeExpression(new
CodeThisReferenceExpression(), _initMethodName));
typeDecl.Members.Add(ctor);
}

return method;
}

/// <include file='doc\ComponentTypeCodeDomSerializer.uex'
path='docs/doc[@for="ComponentTypeCodeDomSerializer.GetInitializeMethods"]/*
' />
/// <devdoc>
/// This method returns an array of methods that need to be
interpreted during deserialization.
/// The default implementation returns a single element array
with the constructor in it.
/// </devdoc>
protected override CodeMemberMethod[]
GetInitializeMethods(IDesignerSerializationManager manager,
CodeTypeDeclaration typeDecl) {
if (manager == null) {
throw new ArgumentNullException("manager");
}

if (typeDecl == null) {
throw new ArgumentNullException("typeDecl");
}

foreach (CodeTypeMember member in typeDecl.Members) {
CodeMemberMethod method = member as CodeMemberMethod;

// Note: the order is important here for performance!
// method.Parameters causes OnMethodPopulateParameters
callback and therefore it is much more
// expensive than method.Name.Equals

if (method != null && method.Name.Equals(_initMethodName)
&& method.Parameters.Count == 0 ) {
return new CodeMemberMethod[] { method };
}
}

return new CodeMemberMethod[0];
}
}

You'd have to do something similar in your own custom TypeCodeDomSerializer.

Hope this helps.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
eschneider
2008-04-15 14:36:06 UTC
Permalink
That could only work for new Forms or new Root designers.
How can I intercept existing root designers?

Thanks,
Schneider
Post by Linda Liu[MSFT]
Hi Schneider,
I got a reply from an expert in the WinForm design time field.
He said that to control the code generation of a root object like a form,
we need to derive from the TypeCodeDomSerializer class to implement the
code generation we like. Then add a DesignerSerializerAttribute to the form
[DesignerSerializer(typeof(MyTypeSerializer),
typeof(TypeCodeDomSerializer))]
public class MyCustomForm : Form {
}
class MyTypeSerializer:TypeCodeDomSerializer
{}
TypeCodeDomSerializer does most of what you want, so you can simply derive
from it. The one thing it doesn't know about is "InitializeComponent".
internal class ComponentTypeCodeDomSerializer : TypeCodeDomSerializer {
private static object _initMethodKey = new object();
private const string _initMethodName = "InitializeComponent";
private static ComponentTypeCodeDomSerializer _default;
internal new static ComponentTypeCodeDomSerializer Default {
get {
if (_default == null) {
_default = new ComponentTypeCodeDomSerializer();
}
return _default;
}
}
/// <include file='doc\ComponentTypeCodeDomSerializer.uex'
/>
/// <devdoc>
/// This method returns the method to emit all of the
initialization code to for the given member.
/// The default implementation returns an empty constructor.
/// </devdoc>
protected override CodeMemberMethod
GetInitializeMethod(IDesignerSerializationManager manager,
CodeTypeDeclaration typeDecl, object value) {
if (manager == null) {
throw new ArgumentNullException("manager");
}
if (typeDecl == null) {
throw new ArgumentNullException("typeDecl");
}
if (value == null) {
throw new ArgumentNullException("value");
}
CodeMemberMethod method = typeDecl.UserData[_initMethodKey] as
CodeMemberMethod;
if (method == null) {
method = new CodeMemberMethod();
method.Name = _initMethodName;
method.Attributes = MemberAttributes.Private;
typeDecl.UserData[_initMethodKey] = method;
// Now create a ctor that calls this method.
CodeConstructor ctor = new CodeConstructor();
ctor.Statements.Add(new CodeMethodInvokeExpression(new
CodeThisReferenceExpression(), _initMethodName));
typeDecl.Members.Add(ctor);
}
return method;
}
/// <include file='doc\ComponentTypeCodeDomSerializer.uex'
' />
/// <devdoc>
/// This method returns an array of methods that need to be
interpreted during deserialization.
/// The default implementation returns a single element array
with the constructor in it.
/// </devdoc>
protected override CodeMemberMethod[]
GetInitializeMethods(IDesignerSerializationManager manager,
CodeTypeDeclaration typeDecl) {
if (manager == null) {
throw new ArgumentNullException("manager");
}
if (typeDecl == null) {
throw new ArgumentNullException("typeDecl");
}
foreach (CodeTypeMember member in typeDecl.Members) {
CodeMemberMethod method = member as CodeMemberMethod;
// Note: the order is important here for performance!
// method.Parameters causes OnMethodPopulateParameters
callback and therefore it is much more
// expensive than method.Name.Equals
if (method != null && method.Name.Equals(_initMethodName)
&& method.Parameters.Count == 0 ) {
return new CodeMemberMethod[] { method };
}
}
return new CodeMemberMethod[0];
}
}
You'd have to do something similar in your own custom
TypeCodeDomSerializer.
Hope this helps.
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu[MSFT]
2008-04-17 10:13:28 UTC
Permalink
Hi Schneider,

Thank you for your reply!

For existing root designers, you need to derive the exiting Forms from the
base Form which is adorned with the custom type codedom serializer. That's
to say, change the base class of the existing Forms from
System.Windows.Forms.Form to MyCustomForm.

Then reopen the existing Forms in the designer and the code generated in
the InitializeComponent method will change.

Hope this helps.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
eschneider
2008-04-17 14:23:39 UTC
Permalink
Thats not what I'm looking for. I can not expect customers to do that, it
must be automated.
I want to override/intercept all root designers including pre-existing.

Is it not possible to replace a Root designer with-in the serialization
manager?
Can I override or replace the serialization manager?

Thanks,
Schneider
Post by Linda Liu[MSFT]
Hi Schneider,
Thank you for your reply!
For existing root designers, you need to derive the exiting Forms from the
base Form which is adorned with the custom type codedom serializer. That's
to say, change the base class of the existing Forms from
System.Windows.Forms.Form to MyCustomForm.
Then reopen the existing Forms in the designer and the code generated in
the InitializeComponent method will change.
Hope this helps.
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu[MSFT]
2008-04-22 02:36:20 UTC
Permalink
Hi Schneider,

Thank you for your reply!

I'm sorry but I have to say that there may no automated way to
override/intercept all root designers including pre-existing.

Custom code dom serializer only works on a derived class. For example, Form
A has a custom code dom serializer and Form B derives from Form A. When the
Form A is opened in the designer, the custom code dom serializer isn't used
by the designer. However when the Form B is opened in the designer, the
custom code dom serializer is used by the designer.

Hope this helps.
If you have any concern, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
Loading...