I have 2 windowsForm projects (Project A and B) in C #, but I would like to add in Project B the reference to Project A by code and call Project A from within Project B. I used Assembly.Load and it is only working if I remove the Main void arguments.
The form of Project A should be open as MdiParent of Project B.
I tried using Assembly.load and activator.createinstance but it didn't work when I try to pass the method parameter.
With param args is returning an error (System.MissingMethodException: 'Constructor in type' CompareXMLTools.Main 'not found.')
#using System.Reflection.Assembly
Project A Program.cs
namespace CompareXMLTools
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main(args));
}
}
}
WindowsForm
namespace CompareXMLTools
{
public partial class Main : Form
{
public Main(string[] args)
{
InitializeComponent();
ArgsPassed = args;
}
}
}
Project B
namespace XMLValidator
{
public partial class frmMain : Form
{
public frmMain(string[] args)
{
InitializeComponent();
ArgsPassed = args;
}
}
private void tsbrnCompareXML_Click(object sender, EventArgs e)
{
object dllUserControl = null;
System.Reflection.Assembly assembly2 = AppDomain.CurrentDomain.Load(File.ReadAllBytes(@"D:\Projetos C#\XMLValidator\XMLValidator\CompareXMLTools.exe"));
dllUserControl = assembly2.CreateInstance("CompareXMLTools.Main", true, System.Reflection.BindingFlags.Default, null, new string[] { }, System.Globalization.CultureInfo.CurrentCulture, null);
((frmMain)dllUserControl).MdiParent = this;
((frmMain)dllUserControl).Show();
}
}
Note: The Project B command only works if I remove the ** string [] args
** field from the Main Method.
I need to pass arguments when call the new WinForm of project A, how can I do this?
I suggest to add a parameter-less constructor to Form1, so you can call it after from an external assembly that may not know what number of parameters it expects (if any) and add the logic required to handle
null
parameters.After this, if you don't want / can't use Interfaces (to have a common understanding of the contract between these assemblies), you have to rely on your knowledge of what Forms you want to load and call them by
Name
.Parameters can be passed using the Activator.CreateInstance overload tha accepts a Type (you know what type you want to load, a Form) and the arguments in the form of
params object[]
.Each object in
params
represents the arguments expected by a Constructor of the class you specify.A parameter-less constructor doesn't expect any argument, so you pass
null
inargs[0]
.Otherwise,
args[0]
contains the arguments of the non-empty Constructor you want to call, to initialize the class specified.and call:
I suggest to build an intermediate class that handles the initialization of the external assembly, extract some useful information automatically (the
NameSpace
, resources of specific type -Forms
, Project Resources, etc.). so you just need to provide the name of a Form to activate and show it.E.g., from a Menu in your MDIParent Form:
The
ResourceBag
helper class:Maybe add an overload to
public Form LoadForm()
, to pass a differentNameSpace
, in case you want to load a class object that is not part of the defaultNameSpace
.