【问题标题】:How to generate a method in the .designer.cs file如何在 .designer.cs 文件中生成方法
【发布时间】:2014-01-29 17:08:56
【问题描述】:

在自定义 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;
    }
}

【问题讨论】:

    标签: winforms serialization codedom


    【解决方案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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-13
      • 1970-01-01
      • 2012-12-18
      • 2014-07-13
      • 2011-07-11
      • 2021-04-20
      • 1970-01-01
      • 2011-07-01
      相关资源
      最近更新 更多