在自定义CodeDomSerializer中,您可以向该类添加自定义成员(例如事件处理程序方法)。
生成的成员总是以Form1.cs而不是Form1.designer.cs结束。 有没有办法在设计器文件的部分类中插入生成器方法?
(方法的内容将自动生成,不应触及。)
添加方法的示例:
public class MasterDetailControlSerializer : CodeDomSerializer
{
public override object Serialize(IDesignerSerializationManager manager, object value)
{
var baseClassSerializer = manager.GetSerializer(typeof(MasterDetailControl).BaseType, typeof(CodeDomSerializer)) as CodeDomSerializer;
var r = (CodeStatementCollection)baseClassSerializer.Serialize(manager, value);
var masterDetailControl = (MasterDetailControl)value;
var method = new CodeMemberMethod();
method.Name = masterDetailControl.Name + "_InitializeDetailComponent";
method.Parameters.AddRange(new[] { new CodeParameterDeclarationExpression(typeof(object), "sender"), new CodeParameterDeclarationExpression(typeof(InitializeDetailComponentEventArgs), "e") });
method.Attributes = MemberAttributes.Private;
var type = manager.GetService<CodeTypeDeclaration>();
type.Members.Add(method);
r.Add(new CodeAttachEventStatement(
new CodeEventReferenceExpression(base.GetExpression(manager, masterDetailControl), "InitializeDetailComponent"),
new CodeDelegateCreateExpression(
new CodeTypeReference(typeof(EventHandler<InitializeDetailComponentEventArgs>)),
new CodeThisReferenceExpression(),
method.Name
)));
return r;
}
}
答案 0 :(得分:1)
经过一些研究,逐步介绍Visual Studio代码,这非常有效:
public class MasterDetailControlSerializer : CodeDomSerializer
{
private static void AddToDesignerTypeDeclaration(IDesignerSerializationManager manager, CodeTypeMember member)
{
var type = manager.GetService<CodeTypeDeclaration>();
var initializeComponentMethod = type.Members.Cast<CodeTypeMember>().First(m => m.Name == "InitializeComponent");
var designerTypeDeclaration = ((CodeTypeDeclaration)initializeComponentMethod.UserData[typeof(CodeTypeDeclaration)]);
member.UserData[typeof(CodeTypeDeclaration)] = designerTypeDeclaration;
member.UserData[typeof(CodeDomProvider)] = initializeComponentMethod.UserData[typeof(CodeDomProvider)];
for (var i = 0; i < type.Members.Count; i++)
if (type.Members[i].Name == member.Name)
{
type.Members.RemoveAt(i);
break;
}
for (var i = 0; i < designerTypeDeclaration.Members.Count; i++)
if (designerTypeDeclaration.Members[i].Name == member.Name)
{
designerTypeDeclaration.Members.RemoveAt(i);
break;
}
// Must add to the main type declaration or Visual Studio will remove the method later.
// The order of these two statements matters!
type.Members.Add(member);
// Add to the type declaration that goes in the designer file
designerTypeDeclaration.Members.Add(member);
}
public override object Serialize(IDesignerSerializationManager manager, object value)
{
var baseClassSerializer = (CodeDomSerializer)manager.GetSerializer(typeof(MasterDetailControl).BaseType, typeof(CodeDomSerializer));
var r = (CodeStatementCollection)baseClassSerializer.Serialize(manager, value);
var masterDetailControl = (MasterDetailControl)value;
var detailInitializationMethod = new CodeMemberMethod();
detailInitializationMethod.Name = masterDetailControl.Name + "_InitializeDetailComponent";
detailInitializationMethod.Parameters.AddRange(new[] { new CodeParameterDeclarationExpression(typeof(object), "sender"), new CodeParameterDeclarationExpression(typeof(InitializeDetailComponentEventArgs), "e") });
detailInitializationMethod.Attributes = MemberAttributes.Private;
AddToDesignerTypeDeclaration(manager, detailInitializationMethod);
r.Add(new CodeAttachEventStatement(
new CodeEventReferenceExpression(base.GetExpression(manager, masterDetailControl), "InitializeDetailComponent"),
new CodeDelegateCreateExpression(
new CodeTypeReference(typeof(EventHandler<InitializeDetailComponentEventArgs>)),
new CodeThisReferenceExpression(),
detailInitializationMethod.Name
)));
return r;
}
}