Hello:
I have posted a bit different version of this question. But, now I want to ask it differently and maybe get my question across.
I have a text field from my TreeView and would like to have it passed to the program and have it open the form with the same name. I don't want to have a bunch of if/else statements for each possibility.
Example: If a text field is entered and its 'Customer' I want to pass that string/text to a routine that will open the 'FormCustomer'. Below is some pseudo code.
e.Node.Name = "Customer"
//FormToOpen FormToOpen = e.Node.Name;
//frm.MdiParent = this;
//FormToOpen.Show();
Hope I explained it a bit better.
Loading
NainilPosted Feb 17, 2010, 2:48 PM
using System.Reflection;
That should probably do it.
You should change the className to be the e.Node.Name or e.Node.Text, depending on your requirements.
NainilPosted Feb 17, 2010, 10:47 PM
I am glad it worked out for you.
GustavoPosted Feb 17, 2010, 7:20 PM
You made me so HAPPY... I love it. Its working really well. I changed the 'nameClass' to 'e.Node.Tag' where I have it populated with the form name for only the ones that need to open the form. It perfect.
Now I will check the forum to see how I can get the' namespace' so I dont have to hard code the value of "ICECPack".
Thank you so much. Hopefully I will learn stuff and be able to help others (Might take me long time, but...)
GustavoPosted Feb 17, 2010, 6:20 PM
YES, YES, YES.
It is now opening the hard coded form.
Below is the code. I changed the namespace and the className. Now I will try to make the string "ICECPack" and "FormLogin" varialbe. I will try to change "FormLogin" to e.Node.Text.
This is cool...
// Test Phase 2
Assembly oAssembly = Assembly.GetEntryAssembly();
Form oFormToOpen = (Form) oAssembly.CreateInstance("ICECPack" + "." + "FormLogin");
oFormToOpen.MdiParent = this;
oFormToOpen.Show();
NainilPosted Feb 17, 2010, 6:12 PM
The Assembly.CreateInstancec() method returns an object of type object. I thought that you had derived all your windows Form instances from a class called FormToOpen which further derives from Form class. But nonetheless, try the following code. It should work:
Assembly oAssembly = Assembly.GetEntryAssembly();
Form oFormToOpen = (Form) oAssembly.CreateInstance(namespace + "." + className);
oFormToOpen.MdiParent = this;
oFormToOpen.Show();
Let me know if this helps.
GustavoPosted Feb 17, 2010, 4:51 PM
Thanks...
Ok, Now I understand the NameSpace and the ClassName ( I think?). So in my project the NameSpace is "ICECPack" and ClassName is "FormLogin".
It is blowing up at... (The line below highlighed in red). It gives me the error: Unable to cast object of type 'ICECPack.FormLogin' to type 'ICECPack.FormToOpen'.
Question: Do I have to have something special to have my main for know of the other child form?
Below is the code at this time.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection; //<<< ADDED per Nainil
namespace ICECPack
{
public partial class FormICECPack : Form
{
public FormICECPack()
{
InitializeComponent();
}
private void buttonLogin_Click(object sender, EventArgs e)
{
// Button to show Login form. For test use only at this time. Needs work.
FormLogin frm = new FormLogin();
frm.MdiParent = this;
frm.Show();
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
}
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
// Nainil sample code
//Assembly oAssembly = Assembly.GetEntryAssembly();
//FormToOpen oFormToOpen = (FormToOpen) oAssembly.CreateInstance(namespace + "." + className);
//oFormToOpen.MdiParent = this;
//oFormToOpen.Show();
Assembly oAssembly = Assembly.GetEntryAssembly();
//namespace = ICECPack
//classname = FormLogin
FormToOpen oFormToOpen = (FormToOpen)oAssembly.CreateInstance("ICECPack.FormLogin");
oFormToOpen.MdiParent = this;
oFormToOpen.Show();
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
NainilPosted Feb 17, 2010, 4:05 PM
Don't worry. I will help you as long as you don't get fed up of me. lol. Back to our problem, the ClassName is the form that you want to open. The namesapce is basically a container which groups classes, enums, structs together. For example the Sysetm.Data.SqlClient is the name space SqlClient (under another namespace Data). The SqlClient namespace contains classes like SqlConnection, SqlDataReader, SqlDbType, SqlCommand etc. It's basically grouping all the similar classes into one single container called namespace (SqlClient namesapce).
Similarly, if you do a search for the keyword "namespace" on your code file in Windows application, you will find the namesapce in your application. The namespace starts right after all the "using" statements. All the classes, enums, structs, in your application should be listed under a namespace. That is the namspace you would want to use. Let me konw if this helps.
GustavoPosted Feb 17, 2010, 3:50 PM
Thanks for your help. Its still not working, but I will try to make it work. Its getting closer. If I dont get it to work after a few hours, I will post again. Then maybe if you are not fed up with me, you will help me again. I REALLY appreciate your help.
I have to figure out what is NameSpace?
From you examples, I guess the ClassName is the name of the form I want to open. In this case just for testing its "FormLogin".
NainilPosted Feb 17, 2010, 3:24 PM
FomrLogin oFormToOpen = (FormLogin) oAssembly.CreateInstance("Namespace.FormLogin");
Try this and see.
GustavoPosted Feb 17, 2010, 3:20 PM
Thanks... the "using System.Reflection; " fixed that error. I really appreciate your help.
Now I have this issue when I run it.
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
//MessageBox.Show("Hello:" + e.Node.Name);
//TreeNode node = treeViewICEPack.SelectedNode;
//MessageBox.Show("TreeNode node= " + node);
Assembly oAssembly = Assembly.GetEntryAssembly();
//FormToOpen oFormToOpen = (FormToOpen) oAssembly.CreateInstance(namespace + "." + className);
FormToOpen oFormToOpen = (FormToOpen) oAssembly.CreateInstance("FormLogin.cs"); //<<< hard coded this to try to have it run.
oFormToOpen.MdiParent = this; //<<< This give me a NullRefernceExeption
oFormToOpen.Show();
}
GustavoPosted Feb 17, 2010, 2:39 PM
I have been playing around with it and surfing to try to find out what I am missing. I am getting the following errors: The red underlined variables are the errors. Do I have to define 'Assembly' somewhere? The 'classname' what should I change it to? Sorry, I am a real super newbie...lol
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
//MessageBox.Show("Hello:" + e.Node.Name);
//TreeNode node = treeViewICEPack.SelectedNode;
//MessageBox.Show("TreeNode node= " + node);
Assembly oAssembly = Assembly.GetEntryAssembly();
FormToOpen oFormToOpen = (FormToOpen)oAssembly.CreateInstance(e.Node.Name + "." + className);
oFormToOpen.MdiParent = this;
oFormToOpen.Show();
}
NainilPosted Feb 17, 2010, 2:28 PM
You are correct. You need to put the code in the NodeMouseClick event. Make sure you are providing the correct namespace ortherwise you will get a null object.
GustavoPosted Feb 17, 2010, 12:34 PM
Thanks for the reply. I am a super newbie to Visual Studio 2008 C# so I dont understand fully where to put these lines that you have given me, but it will give me a starting point. Thanks much.
Below is what code I have as a start:
In the section "treeView1_NodeMouseClick", is where I need the code, I think.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ICECPack
{
public partial class FormICEPack : Form
{
public FormICEPack()
{
InitializeComponent();
}
private void toolStripStatusLabel1_Click(object sender, EventArgs e)
{
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void buttonLogin_Click(object sender, EventArgs e)
{
// Button to show Login form. For test use only at this time. Needs work.
FormLogin frm = new FormLogin();
frm.MdiParent = this;
frm.Show();
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
}
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
//MessageBox.Show("Hello:" + e.Node.Name);
//TreeNode node = treeViewICEPack.SelectedNode;
//MessageBox.Show("TreeNode node= " + node);
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
NainilPosted Feb 17, 2010, 12:15 PM
You can use Assembly class (System.Reflection) to create dynamic instances of a class. You should do the following:
1. Create an Assembly instance
2. Use the Assembly instance and call the CreateInstance(Namespace + ClassName) function (where Namespace is the Namespace of the class and the className is the name of the class)
3. Cast the returning object to the expected object type.
Following is the code snippet:
Assembly oAssembly = Assembly.GetEntryAssembly();
FormToOpen oFormToOpen = (FormToOpen) oAssembly.CreateInstance(namespace + "." + className);
oFormToOpen.MdiParent = this;
oFormToOpen.Show();
The object oFormToOpen will be the new FormToOpen object and then you can use it like a normal object.