Reputation: 51
I'm just starting Project Euler and I have already ran into my first issue. I want to have a separate form for every Euler Problem but I cannot figure out how to open the forms in a good way. What I want to do is use the variable problemNumber to open a form. For example if I have problemNumber set to 54 and I press a button it should open form54.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int problemNumber = int.Parse(numericUpDown1.Text);
}
}
}
I do know how to open a specific form, for example form2.
form2 f2 = new form2();
f2.Show();
This would open up form2, but as mentioned above I want to open up form+problemNumber.
Thank you!
Upvotes: 5
Views: 149
Reputation: 69372
You could create a simple method which takes in the name of the form (you can change the namespace to the name of your project, I've just used the default WindowsFormApplication1
). You can then name each form Project{x}
.
public static Form GetForm(string id)
{
return Assembly.GetExecutingAssembly().CreateInstance(String.Format("WindowsFormsApplication1.Project{0}", id)) as Form;
}
And use it like this
Form firstProjectForm = GetForm("1");
if(firstProjectForm != null)
firstProjectForm.Show();
Upvotes: 0
Reputation: 3316
There may be better ways to handle launching multiple forms than using the class name. However, here is some code that does what you asked, showing how you can call other methods than just Show. Change "yourNamespace."
using System.Reflection;
Type t = Type.GetType("yourNamespace.Form" + numericUpDown1.Text);
if (t!=null)
{
object instance = Activator.CreateInstance(t);
MethodInfo mI = t.GetMethod("Show", new Type[0]);
mI.Invoke(instance, null);
}
Upvotes: 0
Reputation: 9394
I've made a small sample application to find a Form by name. The code to find the Form is
var types = Assembly.GetExecutingAssembly().GetTypes();
var targetForm = types.FirstOrDefault(t => t.IsClass && t.Name == string.Format("Form{0}", formNumber);
if (targetForm != null)
{
var form = (Form)Activator.CreateInstance(targetForm);
form.ShowDialog();
}
Upvotes: 1
Reputation: 7830
One possibility would be to create a static class, that has one static method with a switch case and returns a Form
object. In the method you create new form object regarding the specified number:
public static class FormStarter
{
public static Form OpenForm(int formNumber)
{
Form form = null;
switch (formNumber)
{
case 1: form = new Form1(); break;
case 2: form = new Form2(); break;
//case 3: form = new Form3(); break;
// ...
default: throw new ArgumentException();
}
return form;
}
}
You can then use the class like this:
var f = FormStarter.OpenForm(2);
f.ShowDialog(); // Form2 is started!
Once you have a new form, you need to add the creation of the instance in only one method - the OpenForm
.
Another possible solution without a static class would be a Dictionary
object holding the number and the form instance like this:
Dictionary<int, Form> forms = new Dictionary<int, Form>();
forms.Add(1, new Form1());
forms.Add(2, new Form2());
forms[2].ShowDialog(); // Form2 is started!
If you want to reference just the type of the form in the dictionary and create an instance only when needed, then change the value of the dictionary to be of type Type
and put the corresponding form in it:
Dictionary<int, Type> forms = new Dictionary<int, Type>();
forms.Add(1, typeof(Form1));
forms.Add(2, typeof(Form2));
((Form)Activator.CreateInstance(forms[2])).ShowDialog(); // Form2 is started!
Upvotes: 2