我一直想从文件夹中加载用户控件。我希望人们能够为我的应用打包扩展程序。为此,他们必须创建一个c#用户控件,并将设计器,代码和resx文件放入文件夹中。然后,当他们想使用其“扩展名”时,他们将从文件夹选择器中选择一个文件夹(我有),我的应用程序将加载其扩展名。我想专门拉出用户控件并将其转换为用户控件对象。我可以这样做吗?如果可以,怎么办?
我环顾了互联网,似乎与这个问题几乎没有任何联系。我无法创建任何可以完成此任务的脚本。我什至不知道从哪开始。我知道我必须编译他们的usercontrol。
如果这不可能,那么我能想到的下一个最佳解决方案可能是预编译的用户控件。如果可能的话,我该如何加载?
任何帮助将不胜感激。谢谢!
答案 0 :(得分:1)
如果您希望编译源代码,可以使用System.CodeDom
完成。除此之外,您还应该从程序集中加载类型并进行测试以查看其中是否有UserControl
,然后将其加载并添加到表单中。
以下是我所描述的一些示例:
public void LoadPlugin(params string[] sourceCodeFilesForUserControl)
{
// Compile the source files
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.IncludeDebugInformation = true;
parameters.GenerateInMemory = true;
// Add references that they can use
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll"); // important for UserControl
parameters.TreatWarningsAsErrors = false;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, sourceCodeFilesForUserControl);
if (results.Errors.Count > 0)
{
// Handle compile errors
StringBuilder sb = new StringBuilder();
foreach (CompilerError CompErr in results.Errors)
{
sb.AppendLine("Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";");
}
Console.Write(sb.ToString());
}
else
{
// The assembly we can search for a usercontrol
var assembly = results.CompiledAssembly;
// If the assembly was already compiled you might want to load it directly:
// assembly = Assembly.LoadFile(@"C:\Program Files\MyTool\plugins\someplugin.dll");
// Get the first type in the assembly that is a UserControl
var userControl = assembly.GetTypes().FirstOrDefault(x => x.BaseType == typeof(UserControl));
// Create a instance of the UserControl
var createdUserControl = Activator.CreateInstance(userControl, new object[] { }) as UserControl;
// Add the created UserControl to the current form
this.Controls.Add(createdUserControl);
}
}