Mit dynamisch erstelltem Code Windows Formselemente der Form hinzufügen

bittmann1994

Grünschnabel
Hallo liebe Community,

ich bin eigentlich nicht der Typ der gleich bei der Suche auf gibt, jedoch stehe ich jetz vor einem Problem das schier unlösbar scheint.

Und zwar:

ich habe folgenden Code genutzt um dynamisch Code meinem Programm zufügen zu können und habe das Problem, dass ich aber egal wie ich es mache, keine GUI Elemente hizufügen kann. Hat da jemand irgendwelche tipps? Danke schon mal im voraus. :)

C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.CodeDom.Compiler;
 
namespace testcodebox
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateInMemory = true;
            parameters.ReferencedAssemblies.Add("System.dll");
            parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
 
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(@"using System;");
            sb.AppendLine(@"using System.Text;");
            sb.AppendLine(@"using System.Windows.Forms;");
            sb.AppendLine(@"public class Test{");
            sb.AppendLine(@"public void Funktion(){");
            sb.AppendLine(richTextBox1.Text);
            sb.AppendLine(@"}}");
 
            CompilerResults result = provider.CompileAssemblyFromSource(parameters, sb.ToString());
            listBox1.DataSource = result.Errors;
            listBox1.DisplayMember = "ErrorText";
            if (!result.Errors.HasErrors)
            {
                object instance = result.CompiledAssembly.CreateInstance("Instance");
                MethodInfo info = instance.GetType().GetMethod("Funktion");
                info.Invoke(instance, null);
            }
        }
    }
}
 
Zuletzt bearbeitet von einem Moderator:
Hallo bittmann1994

Es gibt hier Tags für den code (werden im Editor angezeigt), für CSharp wäre das [code=csharp]this is my code[/code].

Der Code den du compilierst sieht folgendermassen aus:
C#:
using System;
using System.Text;
using System.Windows.Forms;

public class Test
{
	public void Funktion() 
	{
		richTextBox1.Text;
	}
}

Ich denke du siehst bereits das Problem, bzw die Probleme:
- Klassen müssen in einem Namespace sein
- Woher kommt richTextBox1?
- Codezeilen müssen entweder Funktionsaufrufe, assignments oder new-Aufrufe sein

Angenommen es würde dennoch compilieren schauen wir, was du nacher machst:
C#:
object instance = result.CompiledAssembly.CreateInstance("Instance");

Woher nimmst du den Typen Instance?

Viele Grüsse
Cromon
 
Hallo Cromon,
richTextBox1 ist eine RichTextbox auf meiner Form. Der Code, wie er oben steht funktioniert auch so. Also wenn ich z. B. eine MessageBox ausgebe ist dies möglich. Bloß möchte ich über den eingegebenen Code in der RichTextBox, der Form auf der dir RTB drauf ist z.B. einen Button hinzufügen.
 
Hallo bittmann1994

Das ist durchaus möglich, dass diese richTextBox1 in deiner Klasse existiert, sie existiert aber nicht in der Klasse Test.

Viele Grüsse
Cromon

PS:
Selbst wenn sie das täte würdest du folgenden Fehler erhalten:
error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
 
Hallo bittmann1994

So wie du es bei jeder anderen Klasse auch machst, du musst die Argument an die Klasse übergeben, entweder über eine Methode oder den Konstruktor und dann in der Klasse als Feld speichern.

Viele Grüsse
Cromon
 
Zurück