Windows Develop Bookmark and Share   
 index > Windows Forms General > CodeDom & InitializeComponent
 

CodeDom & InitializeComponent

Trying to replicate the 'InitializeComponent" method of the designer for a form creator I'm building and I can't seem to get the InitializeComponent / Algorithm correct.

Has anyone a link to an article or code snippet dealing specifically with replicating this method?

Thaks,

PAS
MigrationUser 1  Tuesday, September 21, 2004 3:40 PM
What specifically is the problem you're running into?  

The forms designer does several things, but there is nothing special about the InitializeComponent method.  The designer simply uses it to initialize the controls and components on the form.
MigrationUser 1  Tuesday, September 21, 2004 9:59 PM
I'm having trouble generating the code for an InitializeComponent method via CodeDom.
I'm building a simple IDE for designing a specific type of form.  For each control on the design surface I need to initialize it as does VS.Net's InitializeComponent.  Some sample code I've found looks like this:


            // build our InitializeComponent method
            //
            CodeMemberMethod initComp = new CodeMemberMethod();
            initComp.Name = "InitializeComponent";
            initComp.ReturnType = new CodeTypeReference("void");
            initComp.Attributes = MemberAttributes.Private;
            initComp.Comments.Add(new CodeCommentStatement());
            initComp.Comments.Add(new CodeCommentStatement("Initialize form controls", false));
            // add the statements to the init components method
            //
            
                initComp.Statements.Add(
                new CodeAssignStatement(
                new CodeFieldReferenceExpression(
                new CodeThisReferenceExpression(), "MyForm"),
                new CodeObjectCreateExpression(
                new CodeTypeReference(typeof(System.Windows.Forms.Form).ToString(),
                0))));

              _class.Members.Add(initComp);


This should generate the following line of source code (abbreviated):

this.MyForm = new MyForm();


It does not seem to be working though so I'm looking for examples of generating an InitializeComponent method via CodeDom.

Thanks.


MigrationUser 1  Wednesday, September 22, 2004 11:32 AM
Again, there is nothing special about the InitializeComponent method, at least as far as generating the code goes.  You'd generate code for it the same you would any other method.  MSDN is a good source for info about code generation using the classes in the System.CodeDom namespace, so I'd start there if you have specific questions.

You didn't mention what was happening when you run this code, so I can only guess.  With that said, the code you posted looks fine expect for a couple small problems.  This line:initComp.Comments.Add(new CodeCommentStatement());
 will cause a NullReferenceException.  If you just want the comment characters (// in C#), but no comment text, you can pass an empty string to the contsructor of CodeCommentStatement.  

Also, this line may cause problems:initComp.ReturnType = new CodeTypeReference("void");If you want to pass a string for the return type, you should give the full name (System.Void in this case).  An overload of the constructor takes a Type object, so you could remove any doubt by passing typeof(System.Void).

Here's some code showing how to generate a class with this method (I don't know whether you need a sample or not, but I love writing code, so here goes anyway ;))
// This is what will hold the whole ball
// of wax when we're done
CodeCompileUnit codeUnit = new CodeCompileUnit();

// This is the namespace that will contain
// our class
CodeNamespace ns = new CodeNamespace("WindowsForms.Example");

// And here's the actual class
CodeTypeDeclaration myClass = new CodeTypeDeclaration("MyClass");

// I'm guessing you want to derive from Form
myClass.BaseTypes.Add(typeof(System.Windows.Forms.Form));

myClass.Members.Add(new CodeMemberField(typeof
   (System.Windows.Forms.Form), "MyForm"));

// Build the method

/****************************************
 * Here's the code you posted
 ***************************************/

// build our InitializeComponent method
//

CodeMemberMethod initComp = new CodeMemberMethod();

initComp.Name = "InitializeComponent";

initComp.ReturnType = new CodeTypeReference("System.Void"); // Full name

initComp.Attributes = MemberAttributes.Private;

initComp.Comments.Add(new CodeCommentStatement("")); // empty string

initComp.Comments.Add(new CodeCommentStatement("Initialize form controls", false));

// add the statements to the init components method

//

initComp.Statements.Add(

   new CodeAssignStatement(

   new CodeFieldReferenceExpression(

   new CodeThisReferenceExpression(), "MyForm"),

   new CodeObjectCreateExpression(

      new CodeTypeReference(typeof(System.Windows.Forms.Form).ToString(),

      0))));

/************************************
 * End posted code section
 ************************************/

// Add the method to the class...
myClass.Members.Add(initComp);

// the class to the namespace...
ns.Types.Add(myClass);

// and the namespace to the CodeCompileUnit
codeUnit.Namespaces.Add(ns);

// We'll use this to get the code generator
CSharpCodeProvider codeProvider = new CSharpCodeProvider();

ICodeGenerator generator = codeProvider.CreateGenerator();

// This isn't strictly necessary.  You can just
// create a new CodeGeneratorOptions object when
// you generate the code and accept the defaults.
// I just happen to not like the openening brace on the
// same line as the declaration
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BlankLinesBetweenMembers = true;
options.ElseOnClosing = false;
options.BracingStyle = "C";

// This is what we'll write the generated code to
IndentedTextWriter writer = new IndentedTextWriter(new StreamWriter("MyClass.cs"));

// Generate the code, passing the CodeCompileUnit,
// output stream, and generator options
generator.GenerateCodeFromCompileUnit(codeUnit, writer, options);

// clean up
writer.Close();






And here is the contents of MyClass.cs:
//------------------------------------------------------------------------------
// <autogenerated>
//     This code was generated by a tool.
//     Runtime Version: 1.1.4322.573
//
//     Changes to this file may cause incorrect behavior and will be lost if 
//     the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------

namespace WindowsForms.Example
{
    
    
    public class MyClass : System.Windows.Forms.Form
    {
        
        private System.Windows.Forms.Form MyForm;
        
        // 
        // Initialize form controls
        private void InitializeComponent()
        {
            this.MyForm = new System.Windows.Forms.Form();
        }
    }
}
MigrationUser 1  Wednesday, September 22, 2004 6:57 PM
Thanks for your efforts.  I've pretty much got down the generation of the code.  There were a few CodeDom methods I was unaware of that had I taken the time to read more closely would have perhaps saved me some time.

And thaks for your sample code too!

Regards,

Pete
MigrationUser 1  Thursday, September 23, 2004 10:01 AM
The VisualBasic.NET version of this process:

Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.IO
Imports Microsoft.CSharp
Imports Microsoft.VisualBasic
'Imports Microsoft.JScript

Module EntryPoint

#Region "Enums"
    Friend Enum ParserType
        CSharpCode = 15
        VBasicCode = 16
        JSharpCode = 17
    End Enum
#End Region

    Private CodeType As ParserType = ParserType.VBasicCode
    Private CodeProvider As System.CodeDom.Compiler.CodeDomProvider = New VBCodeProvider

    Sub Main()
        ' Create the Unit
        Dim Unit As CodeCompileUnit = New CodeCompileUnit

        ' Define a namespace and add Imports statements
        Dim Namespaces As CodeNamespace = _
          New CodeNamespace("Test.CreateForm")
        Namespaces.Imports.Add( _
          New CodeNamespaceImport("System"))
        Namespaces.Imports.Add( _
          New CodeNamespaceImport("System.Drawing"))
        Namespaces.Imports.Add( _
          New CodeNamespaceImport("System.Windows.Forms"))
        Namespaces.Imports.Add( _
          New CodeNamespaceImport("System.Xml"))
        Namespaces.Imports.Add( _
          New CodeNamespaceImport("System.Data"))

        Unit.Namespaces.Add(Namespaces)

        ' Declare the type including base type
        Dim MyType As CodeTypeDeclaration = _
          New CodeTypeDeclaration("Form1")
        MyType.IsClass = True
        MyType.TypeAttributes = Reflection.TypeAttributes.Public
        MyType.BaseTypes.Add("System.Windows.Forms.Form")

        Namespaces.Types.Add(MyType)

        ' Create the constructor/Sub New and add code
        Dim Constructor As CodeConstructor = _
          New CodeConstructor

        Constructor.Attributes = MemberAttributes.Public
        Constructor.Statements.Add( _
          New CodeMethodInvokeExpression( _
            New CodeThisReferenceExpression, _
                "InitializeComponent", New CodeExpression() {}))

        MyType.Members.Add(Constructor)

        ' Declare component container
        MyType.Members.Add( _
            New CodeMemberField("System.ComponentModel.    IContainer", "components"))

        ' Implement the Dispose method
        Dim DisposeMethod As CodeMemberMethod = _
          New CodeMemberMethod

        DisposeMethod.Name = "Dispose"
        DisposeMethod.Attributes = _
          MemberAttributes.Family Or MemberAttributes.Overloaded _
          Or MemberAttributes.Override

        DisposeMethod.Parameters.Add( _
          New CodeParameterDeclarationExpression( _
            GetType(Boolean), "disposing"))

        Dim Statement As CodeConditionStatement = _
          New CodeConditionStatement
        Statement.Condition = _
          New CodeArgumentReferenceExpression("disposing")

        Dim TrueStatement As CodeConditionStatement = _
          New CodeConditionStatement
        TrueStatement.Condition = _
          New CodeBinaryOperatorExpression( _
            New CodeArgumentReferenceExpression("components"), _
            CodeBinaryOperatorType.IdentityInequality, _
            New CodePrimitiveExpression(Nothing))


        TrueStatement.TrueStatements.Add( _
          New CodeMethodInvokeExpression( _
            New CodeFieldReferenceExpression(Nothing, _
                "components"), "Dispose", New _
                                          CodeExpression() {}))

        Statement.TrueStatements.Add(TrueStatement)

        DisposeMethod.Statements.Add(Statement)

        DisposeMethod.Statements.Add( _
          New CodeMethodInvokeExpression( _
              New CodeBaseReferenceExpression, _
              "Dispose", New CodeArgumentReferenceExpression() _
              {New CodeArgumentReferenceExpression( _
                "disposing")}))

        MyType.Members.Add(DisposeMethod)


        ' InitializeComponent
        Dim InitializeMethod As CodeMemberMethod = New CodeMemberMethod

        InitializeMethod.Name = "InitializeComponent"
        InitializeMethod.Attributes = MemberAttributes.Private

        InitializeMethod.CustomAttributes.Add( _
          New CodeAttributeDeclaration( _
            "System.Diagnostics.DebuggerStepThrough"))

        InitializeMethod.Statements.Add( _
          New CodeAssignStatement( _
            New CodeFieldReferenceExpression( _
              New CodeThisReferenceExpression, "components"), _
                New CodeObjectCreateExpression( _
                  New CodeTypeReference( _
                    GetType(System.ComponentModel.Container)), _
                    New CodeExpression() {})))

        MyType.Members.Add(InitializeMethod)

        ' Main entry point
        Dim MainMethod As CodeEntryPointMethod = New CodeEntryPointMethod
        MainMethod.Name = "Main"
        MyType.Members.Add(MainMethod)

        ' Add mouse move event
        Dim eventstate As New CodeMemberEvent
        eventstate.Name = "MouseMove"
        eventstate.Attributes = MemberAttributes.Final Or MemberAttributes.Public
        eventstate.Type = New CodeTypeReference("System.Windows.Forms.MouseEventHandler")
        MyType.Members.Add(eventstate)

        Dim OutputName As String = "Form1" + GetFileExtension()
        ' Write the source code
        Dim sw As StreamWriter = New StreamWriter(OutputName)
        sw.AutoFlush = True
        Try
            Dim Generator As ICodeGenerator = _
              (CodeProvider).CreateGenerator

            Generator.GenerateCodeFromCompileUnit( _
              Unit, sw, Nothing)
        Finally
            sw.Close()
        End Try

        ' Create the compiler
        Dim Compiler As ICodeCompiler = _
          (CodeProvider).CreateCompiler()

        ' Create the compiler options
        ' Include referenced assemblies
        Dim Options As CompilerParameters = _
          New CompilerParameters
        Options.GenerateExecutable = True
        Options.OutputAssembly = "TestForm1.exe"
        Options.CompilerOptions = "/target:winexe"
        Options.MainClass = "Test.CreateForm.Form1"
        Options.ReferencedAssemblies.AddRange( _
          New String() {"System.dll", "System.Data.dll", _
        "System.Drawing.dll", "System.Windows.Forms.dll", _
        "System.XML.dll"})

        ' Build and look for compiler errors
        Dim Result As CompilerResults = _
          Compiler.CompileAssemblyFromFile(Options, OutputName)

        Dim E As CompilerError
        If (Result.Errors.Count > 0) Then
            For Each E In Result.Errors
                Console.WriteLine(E.ErrorText)
            Next
        Else
            Console.WriteLine("compiled successfully")
        End If
        Console.WriteLine("press enter to continue")
        Console.ReadLine()
    End Sub

#Region "GetFileExtension"
    Private Function GetFileExtension() As String
        Try
            Select Case CodeType
                Case ParserType.CSharpCode
                    Return ".cs"
                Case ParserType.JSharpCode
                    Return ".jsl"
                Case ParserType.VBasicCode
                    Return ".vb"
            End Select
        Catch ex As Exception

        End Try
    End Function
#End Region

End Module

MigrationUser 1  Monday, October 11, 2004 12:54 PM

You can use google to search for other answers

Custom Search

More Threads

• Imaging for windows
• Tab Control
• WinForms with Large Datasets
• ToolStripContainer and MDI
• How to draw clickable text?
• MaskedTextBox - why doesn't ExcludePromptAndLiterals work all the time?
• how to add events to a button created at runtime? vb.net 2008
• all i want to do is draw a circle on the form
• validating form entry
• process hiding