I have this generic method to open forms inside a panel, this method inherits from Form
, currently with the restriction that it has an empty constructor(where T : Form, new())
private void AbrirFormulario<T>() where T : Form, new()
{
Form formulario = panel_contenedor.Controls.OfType<T>().FirstOrDefault();
if (formulario!=null)
{
//Si la instancia esta minimizada la dejamos en su estado normal
if (formulario.WindowState == FormWindowState.Minimized)
{
formulario.WindowState = FormWindowState.Normal;
}
//Si la instancia existe la pongo en primer plano
formulario.BringToFront();
return;
}
//Se abre el form
formulario = new T();
formulario.TopLevel = false;
panel_contenedor.Controls.Add(formulario);
panel_contenedor.Tag = formulario;
formulario.Show();
}
This way to call it:
AbrirFormulario<FormularioX>();
How can I adapt this function to be able to pass parameters to the form?
In this case I need to pass two parameters to the form, something like this:
AbrirFormulario<FormularioX>(parametro1, parametro2);
But in future you may need to use 1/2/3 parameters depending on the form.
Parameters can vary by type, either:
bool
,string
,int
etc.
Any idea how I can achieve this? , either passing a list of parameters, an optional list (like optional parameters), or something like that?
Environment: Visual Studio 2010 & .NET NetFramework 4.
I find this question very interesting, so I am going to try to give an option, although it may not be the ideal one.
The main problem is that there is no way to force a specific constructor in C#. That leaves us with one possible option (perhaps there are more).
My proposal is to create an Interface to create a method that allows receiving the parameters. This is an example:
Here we define a method,
InicializarParametros
which must be met by forms that implement this interface.Later, in the forms that must be called from the generic form, we add the interface in its definition, and the mandatory method:
Now we define the generic method to open the forms as follows:
Finally, the way to use it would be as follows:
Note that as I have defined the method
InicializarParametros
, examples 2 and 3 will throw an exception for an incorrect number of parameters. It is you who must control it in each case.In the end I have decided to do it with Reflection (C#) . In that case, removing the restriction
new()
to allow forms without parameterless constructors:Now, to create the instance, use
Activator.CreateInstance
:So the complete solution would look like this:
And to use it in these ways:
Final solution:
Actually the best approach to do this is to use a factory method
Func<T>
to build the form:Let's say we have this
Form
, just for testing purposes:With the method like this:
Which is then called like this:
With all the helpful intellisense that goes with it:
So now we're left with self-documenting code, no matter how the form is built, and it's not forcing you to use an interface.
Problems using
params object[] args
:There are now some useful self-documenting features about the constructor, namely that the parameters have names. And using something like this:
It gives the caller no information about what the "arguments" are, what order they belong to, or what they mean. So when we call it like this:
The Intellisense doesn't help you because it only shows that you need to pass some (or no) parameter(s) to the method.
You could override the method and increase params for dynamic parameters.
and its way of use