如何在运行时从源文件创建用户控件及其代码隐藏并加载到面板中?我很确定使用 CodeDom 可以解决这个问题,但不太确定如何去做。谁能为此提供一个简化的例子?提前致谢。
要编译的脚本示例
Option Infer On
Imports System
Imports System.Data
Imports System.Math
Imports System.Web.UI.WebControls
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Namespace Evaluator
Public Class Evaluator
Dim Project As New UserControl
Dim Panel1 As New Panel
Dim WithEvents Button1 As New Button
Dim WithEvents TextBox1 As New TextBox
Public Function GetProject(ByVal ParamArray expr() As Object) As UserControl
'panel 1
Panel1.Style.Add("background-color", "#D9E0E8")
Panel1.Style.Add("padding-top", "5px")
Panel1.Style.Add("margin-top", "5px")
Panel1.Style.Add("width", "490px")
Panel1.Style.Add("height", "30px")
Project.Controls.Add(Panel1)
'button 1
Button1.ID = "Button1"
Button1.Text = "Add"
Button1.Width = 100
AddHandler Button1.Click, AddressOf Button1_Click
Panel1.Controls.Add(Button1)
'textbox 1
TextBox1.ID = "TextBox1"
TextBox1.Width = 200
TextBox1.Text = 0
Panel1.Controls.Add(TextBox1)
Return Project
End Function
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text += 1
End Sub
End Class
End Namespace
示例网页(代码隐藏)来编译它
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filePath = Server.MapPath("script.vb")
Dim provider = VBCodeProvider.CreateProvider("VisualBasic")
Dim opts = New CompilerParameters({"mscorlib.dll", "System.dll", "System.Web.dll", "Microsoft.VisualBasic.dll", "System.Data.dll", "System.Xml.dll", "System.Data.Linq.dll", "System.Core.dll", "System.Drawing.dll", "System.Web.Extensions.dll", "System.Data.DataSetExtensions.dll"})
opts.CompilerOptions = "/t:library"
opts.TreatWarningsAsErrors = False
opts.GenerateExecutable = False
opts.GenerateInMemory = True
Dim cr = provider.CompileAssemblyFromFile(opts, New String() {filePath})
'Check for compile errors
If cr.Errors.Count > 0 Then
HttpContext.Current.Session("_evaluator") = Nothing
For Each err As CompilerError In cr.Errors
Debug.Print(err.ErrorText, err.Line)
Next
Else
'Create the Assembly and store in memory
Dim evaluator As Object = Nothing
evaluator = cr.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
HttpContext.Current.Session("_evaluator") = evaluator
HttpContext.Current.Session("MyAssembly") = cr.CompiledAssembly.FullName
End If
Panel1.Controls.Clear()
Call Evaluate()
End Sub
Public Sub Evaluate()
Try
'Invoke method
Dim Evaluator As Object = CType(HttpContext.Current.Session("_evaluator"), Object)
Dim objResult As Object = Evaluator.GetType.InvokeMember("GetProject", BindingFlags.InvokeMethod + Reflection.BindingFlags.Default, Nothing, Evaluator, Nothing)
If Not objResult Is Nothing Then
Panel1.Controls.Add(objResult)
End If
Catch ex As Exception
Debug.Print(ex.Message)
End Try
End Sub