c# - Cómo usar clases personalizadas con compilación dinámica
dynamic compilation (3)
Debería poder simplemente agregar el estilo a la fuente de la siguiente manera:
var source = File.ReadAllText("form.txt");
source += Environment.NewLine;
source += File.ReadAllText("style.txt");
Tengo un formulario que compilé dinámicamente y tengo una clase de estilo. Cuando copio esta clase de estilo a mi fuente de formulario y la compilo todo funciona bien. Pero, ¿cómo puedo usar esta clase de estilo sin copiarla en mi fuente de formulario? Mi programa principal que compila este formulario tiene esta clase, ¿cómo puedo usarlo? Tal vez puedo pasar la clase de estilo a esto para con compilarlo, como una var?
Fuente del programa:
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Microsoft.CSharp;
namespace dynamic
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
new Thread(newForm).Start();
}
public void newForm()
{
using (CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string>
{
{"CompilerVersion", "v4.0"}
}))
{
var parameters = new CompilerParameters
{
GenerateExecutable = false, // Create a dll
GenerateInMemory = true, // Create it in memory
WarningLevel = 3, // Default warning level
CompilerOptions = "/optimize", // Optimize code
TreatWarningsAsErrors = false // Better be false to avoid break in warnings
};
parameters.ReferencedAssemblies.Add("mscorlib.dll");
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
parameters.ReferencedAssemblies.Add("System.Data.dll");
parameters.ReferencedAssemblies.Add("System.Drawing.dll");
parameters.ReferencedAssemblies.Add("System.Xml.dll");
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
var source = File.ReadAllText("form.txt");
CompilerResults results = provider.CompileAssemblyFromSource(parameters, source);
Type type = results.CompiledAssembly.GetType("myForm.Form1");
object compiledObject = Activator.CreateInstance(type);
type.GetMethod("ShowDialog", new Type[0]).Invoke(compiledObject, new object[] {});
MessageBox.Show("formClosed");
}
}
}
}
Fuente del formulario:
using System;
using System.Windows.Forms;
namespace myForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var newTmr = new Timer { Interval = 1000 };
newTmr.Tick += count;
newTmr.Enabled = true;
}
private void count(Object myObject, EventArgs myEventArgs)
{
timer.Value2 = (Int32.Parse(timer.Value2) + 1).ToString();
}
private void button1_Click(object sender, System.EventArgs e)
{
MessageBox.Show("clicked");
}
private void nsButton1_Click(object sender, EventArgs e)
{
MessageBox.Show("button");
}
}
}
namespace myForm
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.nsTheme1 = new myForm.NSTheme();
this.nsButton1 = new myForm.NSButton();
this.timer = new myForm.NSLabel();
this.nsControlButton1 = new myForm.NSControlButton();
this.nsTheme1.SuspendLayout();
this.SuspendLayout();
//
// nsTheme1
//
this.nsTheme1.AccentOffset = 0;
this.nsTheme1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50)))));
this.nsTheme1.BorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.nsTheme1.Colors = new myForm.Bloom[0];
this.nsTheme1.Controls.Add(this.nsControlButton1);
this.nsTheme1.Controls.Add(this.timer);
this.nsTheme1.Controls.Add(this.nsButton1);
this.nsTheme1.Customization = "";
this.nsTheme1.Dock = System.Windows.Forms.DockStyle.Fill;
this.nsTheme1.Font = new System.Drawing.Font("Verdana", 8F);
this.nsTheme1.Image = null;
this.nsTheme1.Location = new System.Drawing.Point(0, 0);
this.nsTheme1.Movable = true;
this.nsTheme1.Name = "nsTheme1";
this.nsTheme1.NoRounding = false;
this.nsTheme1.Sizable = true;
this.nsTheme1.Size = new System.Drawing.Size(284, 274);
this.nsTheme1.SmartBounds = true;
this.nsTheme1.StartPosition = System.Windows.Forms.FormStartPosition.WindowsDefaultLocation;
this.nsTheme1.TabIndex = 0;
this.nsTheme1.Text = "nsTheme1";
this.nsTheme1.TransparencyKey = System.Drawing.Color.Empty;
this.nsTheme1.Transparent = false;
//
// nsButton1
//
this.nsButton1.Location = new System.Drawing.Point(100, 166);
this.nsButton1.Name = "nsButton1";
this.nsButton1.Size = new System.Drawing.Size(75, 23);
this.nsButton1.TabIndex = 0;
this.nsButton1.Text = "nsButton1";
this.nsButton1.Click += new System.EventHandler(this.nsButton1_Click);
//
// timer
//
this.timer.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Bold);
this.timer.Location = new System.Drawing.Point(91, 82);
this.timer.Name = "timer";
this.timer.Size = new System.Drawing.Size(101, 23);
this.timer.TabIndex = 1;
this.timer.Text = "nsLabel1";
this.timer.Value1 = "Timer: ";
this.timer.Value2 = "0";
//
// nsControlButton1
//
this.nsControlButton1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.nsControlButton1.ControlButton = myForm.NSControlButton.Button.Close;
this.nsControlButton1.Location = new System.Drawing.Point(262, 4);
this.nsControlButton1.Margin = new System.Windows.Forms.Padding(0);
this.nsControlButton1.MaximumSize = new System.Drawing.Size(18, 20);
this.nsControlButton1.MinimumSize = new System.Drawing.Size(18, 20);
this.nsControlButton1.Name = "nsControlButton1";
this.nsControlButton1.Size = new System.Drawing.Size(18, 20);
this.nsControlButton1.TabIndex = 2;
this.nsControlButton1.Text = "nsControlButton1";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 274);
this.Controls.Add(this.nsTheme1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form1";
this.Text = "Form1";
this.nsTheme1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private NSTheme nsTheme1;
private NSButton nsButton1;
private NSControlButton nsControlButton1;
private NSLabel timer;
}
}
Fuente de estilo: http://pastebin.com/CjmQQ9ND
Fuente del proyecto : https://yadi.sk/d/ChtMacrsraD4g Si compila esta fuente, todo funcionará bien. Eso porque uso estilo en el archivo form.txt. Separé la forma del estilo en el archivo form.txt. Tengo este estilo en mi programa principal (se puede ver en la captura de pantalla). ¿Cómo puedo enviar esta clase de estilo a mi formulario compilado dinámicamente, para que form pueda usarlo?
Dentro del archivo Form.txt en lugar de las clases en orden prescribe la macro:
namespace myForm
{
<%THEME%>
}
namespace myForm
{
<%THEMEBASE%>
}
Antes de la compilación, cargue los archivos de estilo y reemplácelos en el formulario de código:
//Load style files
var NSThemeSource = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"../../Class/Style/NSTheme.cs"));
var themeBaseSource = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"../../Class/Style/ThemeBase154.cs"));
var source = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Form.txt"));
//Substitute in the form styles
source = source.Replace("<%THEME%>", NSThemeSource);
source = source.Replace("<%THEMEBASE%>", themeBaseSource);
PD : puede cambiar la acción de compilación de los archivos de estilo en el recurso incrustado para que pueda obtener la clase de estilo de exe. Y use este ayudante - http://www.vcskicks.com/embedded-resource.php
De lo que necesitas cambiar el código a:
var NSThemeSource = ResourceHelper.GetEmbeddedResource("Class/Style/NSTheme.cs");
var themeBaseSource = ResourceHelper.GetEmbeddedResource("Class/Style/ThemeBase154.cs");
En primer lugar, debe hacer públicas las clases, las enumeraciones, etc. en NSTheme.cs y ThemeBase154.cs. (es mejor ponerlo en algún espacio de nombres, en lugar de tenerlos en el espacio de nombres global (dinámico)).
Luego, agregue parameters.ReferencedAssemblies.Add ("dynamic.exe"); a su archivo exe (es posible que desee poner sus estilos en un dll por separado).
Después de eso, en tu form.txt agrega using dynamic;
y elimine los calificadores de new myForm.NSTheme()
(por lo tanto, se convierte en new NSTheme()
).
Ahora puede usar sus estilos sin hacerles frente a su clase de formulario.
En caso de que se pierda algo, verifique los errores de CompilerResults results
para problemas particulares.