以编程方式从文件夹加载用户控件

时间:2018-11-04 03:25:40

标签: c# .net winforms

我一直想从文件夹中加载用户控件。我希望人们能够为我的应用打包扩展程序。为此,他们必须创建一个c#用户控件,并将设计器,代码和resx文件放入文件夹中。然后,当他们想使用其“扩展名”时,他们将从文件夹选择器中选择一个文件夹(我有),我的应用程序将加载其扩展名。我想专门拉出用户控件并将其转换为用户控件对象。我可以这样做吗?如果可以,怎么办?

我环顾了互联网,似乎与这个问题几乎没有任何联系。我无法创建任何可以完成此任务的脚本。我什至不知道从哪开始。我知道我必须编译他们的usercontrol。

如果这不可能,那么我能想到的下一个最佳解决方案可能是预编译的用户控件。如果可能的话,我该如何加载?

任何帮助将不胜感激。谢谢!

1 个答案:

答案 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);
    }
}