2014-01-29 40 views
1

在自定義CodeDomSerializer中,您可以向類中添加自定義成員(例如事件處理程序方法)。如何在.designer.cs文件中生成方法

生成的成員總是以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; 
    } 
} 

回答

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; 
    } 
} 
相關問題