Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Δημιουργία Φόρμας στο Runtime

Îåêßíçóå áðü ôï ìÝëïò geochatz. Τελευταία δημοσίευση από το μέλος KelMan στις 14-02-2006, 22:33. Υπάρχουν 7 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  01-02-2006, 12:34 9108

    Confused [8-)] Δημιουργία Φόρμας στο Runtime

    Λοιπόν θα ήθελα να συζητήσουμε κάτι. Θα με ενδειέφερε να φτιάξω ένα εργαλείο σχεδίασης φόρμας το οποίο να δουλεύει κατά την εκτέλεση του προγράμματος μου. Και για να εξηγήσω καλύτερα θα ήθελα να δώσω τη δυνατότητα σε ένα χρήστη να δημιουργήσει τη δική του φόρμα μέσα στο πρόγραμμα και να την εκτελέσει.

    Έχω βρει δύο άρθρα της Microsoft για το πως να φτιάξεις ένα Form Designer αλλά θα ήθελα να μάθω αν κάποιος έχει κάνει κάτι παρόμοιο. Η σκέψη μου είναι να μπορεί ο χρήστης να φτιάξει μια φόρμα με κάποια controls τα οποία θα έχω ορίσει εγώ (είτε Standard, είτε Custom) και στην συνέχεια να μπορει να εισάγει το SQL Statement (ή το όνομα της Stored Procedure) που θα εκτελεστεί έτσι ώστε να μπορεί να κάνει data bind τα πεδία. Η φόρμα απο ότι έχω δει μπορεί να σωθεί ως XML αρχείο έτσι μπορεί κάποιος να την αποθηκεύσει και αργότερα να την προβάλει ξανα και φυσικά μπορεί να γίνει και compile έτσι ώστε να είναι έτοιμοι σε DLL μορφή.

    Έχει ασχοληθεί κανείς με κάτι παρόμοιο;

    Only two things are infinite, the universe and the human stupidity, and I'm not sure about the former.

    Albert Einstein - US (German-born) physicist (1879 - 1955)
  •  01-02-2006, 14:11 9110 σε απάντηση της 9108

    Απ: Δημιουργία Φόρμας στο Runtime

    Το project που θέλεις να κάνεις είναι εξαιρετικά ενδιαφέρον, αλλά δυστυχώς και αρκετά δύσκολο, όχι τόσο λόγω πολυπλοκότητας, αλλά έλλειψης documentation. Το 2004 που έφτιαχνα έναν παρόμοιο designer, το καλύτερο άρθρο που με βοήθησε αρκετά ήταν το

    http://www.divil.co.uk/net/articles/designers/hosting.asp

    Από εκεί και στο εξής όλα ήταν trial and error, με πολλές επαναλήψεις. Το documentation στο MSDN δυστυχώς δεν πρόκειται να σε βοηθήσει.
    Ένα άλλο πολύ χρήσιμο βοήθημα είναι ο σχετικός κώδικας του Visual Studio. Αυτόν τον βλέπεις ανοίγοντας τις σχετικές assemblies του Visual Studio με τον Reflector, και αντιγράφοντάς τον ξεδιάντροπα :-)

    Καλή τύχη στην προσπάθειά σου. Θα ταλαιπωρηθείς λίγο, αλλά το αποτέλεσμα θα αξίζει τον κόπο!

     


    Νατάσα Μανουσοπούλου
  •  01-02-2006, 15:43 9112 σε απάντηση της 9110

    Απ: Δημιουργία Φόρμας στο Runtime

    Σε ευχαριστώ. Η αλήθεια είναι και αυτό το άρθρο το διάβασα. Ελπίζω να μου βγει. Αν πάντως κάποιος άλλος ξέρει κατι περισσότερο ας το "μπουμπουνίσει"! ;-)
    Only two things are infinite, the universe and the human stupidity, and I'm not sure about the former.

    Albert Einstein - US (German-born) physicist (1879 - 1955)
  •  01-02-2006, 15:50 9113 σε απάντηση της 9108

    Απ: Δημιουργία Φόρμας στο Runtime

    Ρίξε και μια ματιά στο Web Matrix (http://www.asp.net/webmatrix/)
    Αν θυμάμαι καλά, δίνει και το source
    Vir prudens non contra ventum mingit
  •  01-02-2006, 23:15 9127 σε απάντηση της 9113

    Απ: Δημιουργία Φόρμας στο Runtime

    Δοκίμασε το παρακάτω ίσως νά σου κάνει.

    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 CodeBLOCKED EXPRESSION {}))
            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 CodeBLOCKED EXPRESSION {}))
            Statement.TrueStatements.Add(TrueStatement)
            DisposeMethod.Statements.Add(Statement)
            DisposeMethod.Statements.Add(New CodeMethodInvokeExpression(New CodeBaseReferenceExpression, "Dispose", New CodeArgumentReferenceBLOCKED EXPRESSION {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 CodeBLOCKED EXPRESSION {})))
            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 

    Το είχα βρεί κάπου στο INTERNET αλλά δέν θυμάμαι πού.
    Βέβαια θα χρειαστεί λίγο τροποποίηση.


    Ιωάννης Μανουσάκης
  •  14-02-2006, 13:55 9664 σε απάντηση της 9108

    Απ: Δημιουργία Φόρμας στο Runtime

    Εγώ είχα φτιάξει κάτι παρόμοιο σε vb6.

    Ειχα ενα FormDesigner που μπορούσε ο χρήστης να χρησιμοποιήσει μερικά standard controls. ΔΛΔ textbox, options, κλπ.(επιλογές για Fonts στα labels θέσεις και τετοια)

    Τα αποτελεσματα του Designer τα αποθηκευα σε textfile. Οταν άνοιγε η εφαρμογή είχα μία φόρμα που έιχε 1 control από το κάθε ένα (1 λαβελ, 1 τεχτ κλπ) και με το διάβασμα του textfile φόρτωνα σε array τα controls με τα αντίστοιχα options. Λειτουργούσε ικανοποιητικά για την εποχή.

    Ακόμα όλα τα controls ήταν μέσα σε picturebox ώστε να έχω και δυνατότητα scroll μέσα στην φόρμα που πολλές φορές μπορεί να ήταν πιο μικρή από το Layout των controls.

    Σιγουρα τώρα και με το .net υπάρχουν πιο καλές λύσεις.
    -------------------------------
    Κ. Γιαγιάς

    Θα ήθελα να είμαι μέσα στην φωτογραφία και όχι εδώ!!!!

    http://beastie06.wordpress.com
  •  14-02-2006, 22:29 9678 σε απάντηση της 9664

    Απ: Δημιουργία Φόρμας στο Runtime

    Για άλλο πράγμα έψαχνα, αυτό βρήκα: http://msdn.microsoft.com/msdnmag/issues/04/12/CustomFormsDesigner/default.aspx

    Το τελευταίο μέρος του άρθρου, λέει σχετικά με αυτό που θες να κάνεις...


    Vir prudens non contra ventum mingit
  •  14-02-2006, 22:33 9679 σε απάντηση της 9678

    Απ: Δημιουργία Φόρμας στο Runtime

    Επίσης, αυτό εδώ http://www.divil.co.uk/net/articles/designers/hosting.asp έχει και παράδειγμα...


    Vir prudens non contra ventum mingit
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems