• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 392
  • Last Modified:

Refer to Form by String (Visual Studio 2008)

How do I refer to a form in my project by using a string variable?  I'm running Visual Studio 2008.

My main screen has a number of dropdown menus that, when an item is selected, a form will open:

        Dim Mdi_frm_Doors As New frm_Doors
        Mdi_frm_Doors.MdiParent = Me
        Mdi_frm_Doors.Show()

In this example, I am providing the name of the form directly (frm_Doors).  What I would like to do is refer to the form as a string variable.

I'm already doing something similar to access specific controls on other open forms (where str_Field is the name of the control I am accessing):

      frm_1.Controls(str_Field).ForeColor = Color.Red

There's got to be something similar for forms.  NOTE:  The form I am trying to open is not already open, so I cannot use a loop like:

        For Each CurrentForm As Form In Application.OpenForms
            If CurrentForm.Name.IndexOf("frm_Cabinet_Assembly_Detail") >= 0 Then

I would prefer not to create an array of all forms in my project, but rather provide the name of a form as a string directly in the code.  I've tried the following code, but I get a System.ArgumentException error for parameter  typeName@0:

        Dim str_Form As String = "frm_Construction_Methods"

        Dim strFormToOpen As String = "[Solid Explorer]." & str_Form

        Dim obhNew As Runtime.Remoting.ObjectHandle
        obhNew = Activator.CreateInstance(Nothing, strFormToOpen)  ' <<<< Error generated here.
        Dim frmNew As Form = DirectCast(obhNew.Unwrap, Form)

I apologize if I have missed something obvious that has already been posted somewhere - I may not be searching for the correct terminology.

Thank you in advance for your help!

George
0
CIW_George
Asked:
CIW_George
  • 10
  • 9
1 Solution
 
lofCommented:
For that you may use reflection

obviously instead of GetType(Form1).FullName you may specify fully qualified class name
Dim assembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
Dim className As String = GetType(Form1).FullName
Dim window As Form = CType(assembly.CreateInstance(className), Form)
        window.ShowDialog()

Open in new window

0
 
CIW_GeorgeAuthor Commented:
Sorry for the ignorance - what is "fully qualified class name?
Here's what I entered, along with the error:

        Dim assembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly
        Dim className As String = GetType("frm_Junk").fullname      ' <<< Error:  Type expected for "frm_Junk"
        Dim window As Form = CType(assembly.CreateInstance(classname), Form)

What am I doing wrong in line 2?

Thank you for your patience!

George
0
 
lofCommented:
Sorry for assuming too much.

If you want to see the fully qualified name you may do

MessageBox.Show(GetType(frm_Junk).fullname)

it is usually YourDefaultNamespace.YourProject.Classname
and frm_Junk is your class name

what you will have to do is to replace whole GetType(object).FullName with the name to have

Dim assembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly
        Dim className As String = "TheFull.LongName.frm_Junk"
        Dim window As Form = CType(assembly.CreateInstance(classname), Form)


or in one line

     CType(Reflection.Assembly.GetExecutingAssembly().CreateInstance("TheFull.LongName.frm_Junk"), Form).Show()
0
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 
CIW_GeorgeAuthor Commented:
Thank you lof!

I haven't done any serious programming for a while.  I've done a lot of deep stuff in Access, but it's been a while for Visual Basic.  So much has changed since the "old days".  I know VB can do what I want, it's just figuring out where the answer is buried..

Your clarification of the fully qualified name was all I needed.  Now, I'm armed and dangerous (again...).

George
0
 
lofCommented:
a lot of things has changed. VB was 'only' a scripting langauge and now it is a gateway to a powerful .Net framework with it's reflection and a lot of goodies. I'd recommend reading about the framework.

You'll be surprised how many things that used to be tricky are now just a function call.
On the other hand some things that used to be very simple due to scripting nature of the language now require a bit more for some good but not always obvious reasons
0
 
CIW_GeorgeAuthor Commented:
It's the things that used to be simple that are now convoluted that - they're the ones that are tripping me up.

Murach's VB 2008 does a great job on the "top level" stuff, but when you get into things like I just asked about, trees, dgvs, etc., it just takes a lot of time searching the Internet for the answers.  The answers are there, you just gotta' find them, then make some sense out of them.

Oh well, back to work...
0
 
CIW_GeorgeAuthor Commented:
When I execute the following line, the form immediately opens:

        Dim form_Open As Form = CType(ass_Assembly.CreateInstance(class_Name), Form)

Previously, I was using the following code to open the form as a mdi child:

        Dim Mdi_frm_CM_Rollouts As New frm_Junk
        Mdi_frm_CM_Rollouts.MdiParent = Me
        'Mdi_frm_CM_Rollouts.Show()

What problems am I going to run into using your method versus what I have been using?

George
0
 
CIW_GeorgeAuthor Commented:
Forget the "'" (comment) in the 3rd line of my sample - all three lines are valid.
0
 
lofCommented:
if you are using MDI form you should really set MdiParent property.
If you won't the new form won't be inside the MDI form.
0
 
CIW_GeorgeAuthor Commented:
I agree, but nothing after the Dim form_Open line will process, as frm_Junk will open as soon as Dim form_Open is encountered.

I can't execute the 3 mdi lines in my example, since the first line needs to reference a valid form name, and that's not established unti the Dim form_Open statement is processed.  What I think I would need is:

        Dim form_Open As Form = CType(ass_Assembly.CreateInstance(class_Name), Form)
        form_Open.MdiParent = Me
        form_Open.Show()

But I never hit the last two lines.

Thoughts?

0
 
lofCommented:
are you sure there is no .Show() at the end of the first line, as in one of my examples?
0
 
CIW_GeorgeAuthor Commented:
Here's my code for the whole sub.  It goes straight to frm_Junk right after the 'Dim form_Open As Form...' statement - it never hits the Stop.

I sincerely appreciate the time you're spending on this - thank you!

George
--------------------------------------------------------
    Private Sub IDsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnu_CM__IDs.Click

        Static int_Forms As Integer = 0
        Dim int_Count As Integer = 0

        Dim str_Form As String = "frm_Junk"

        Dim ass_Assembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly
        Dim class_Name As String = "Solid_Explorer.frm_Junk"

        Dim form_Open As Form = CType(ass_Assembly.CreateInstance(class_Name), Form)

        Stop   <<<<<  Never hit, goes straight to frm_Junk *******************

        Cursor.Current = Cursors.WaitCursor

        '   Determine number of forms open.

        For Each obj_Form In Application.OpenForms
            If obj_Form.name.ToString.IndexOf(str_Form) >= 0 Then
                int_Count += 1
            End If
        Next

        '   Provide form offset pointer.

        If int_Count = 0 Then
            int_Forms = 0
        Else
            int_Forms += 1
        End If

        queue_Parameters.Clear()
        queue_Parameters.Enqueue(int_Forms)

        '   Open form.

        form_Open.MdiParent = Me
        form_Open.Show()

    End Sub
------------------------------------------------------------------------
0
 
lofCommented:
It is really strange behaviour. I have copied the code and only thing I have changed was the class name, to instantiate something I have locally and everything works fine, I'm getting to stop line.

Could you check default constructor?

It is really hard to guess. If you could provide me with full code or temporary access over TeamViewer or something like that I would be happy to have a closer look and investigate the problem.  
0
 
CIW_GeorgeAuthor Commented:
Cockpit error, my apologies...

I virtually always name things using the underscore rather than the space.  In my "our" code, I was referring to 'Solid Explorer' with an understore between the two words rather than a space.  When I replace the underscore with a space, I hit the Stop line.

But...

When the code gets to "form_Open.MdiParent = Me", I get the following error:

"NullReferenceException occurred:  Object reference not set to an instance of an object."

Within one line of me being estatic!

George
0
 
lofCommented:
The only problem I would expect is if Me.IsMdiParent = false
please check the names or add

Option Explicit On

in the first line of your file, it may help debugging.
Probably the variable name you are using at the beginning and the end differ slightly.
the explicit option turned to on, will help you catch those errors.
0
 
CIW_GeorgeAuthor Commented:
Option Explicit is on (and always is).

Me.IsMdiParent from frm_Menu (where our code in question is located) returns "'IsMdiParent' is not a member of 'frm_Main'.

IsMdiContainer is false for frm_Junk, true for frm_Main.

The 3 troubleshooting tips for the NullReferenceException error are:
  " Use the "new" keyword to create an object instance.
  " Check to determine if the object is null before calling the method.
  " Get general help for this exception.

The 'Dim form_Open As Form =' statement does not appear to verify whether frm_Junk exists.  It's not until we get to 'form_Open.MdiParent = Me' does the program check for frm_Junk, and apparently it can't be found.

For what it's worth, here's my Immediate Window when I Stop after "Dim form_Open as Form =":

? ass_assembly
{System.Reflection.Assembly}
    CodeBase: "file:///D:/Wood/Visual Studio/Solid Explorer/Solid Explorer/bin/Debug/Solid Explorer.EXE"
    EntryPoint: {System.Reflection.RuntimeMethodInfo}
    EscapedCodeBase: "file:///D:/Wood/Visual%20Studio/Solid%20Explorer/Solid%20Explorer/bin/Debug/Solid%20Explorer.EXE"
    Evidence: {System.Security.Policy.Evidence}
    FullName: "Solid Explorer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
    GlobalAssemblyCache: False
    HostContext: 0
    ImageRuntimeVersion: "v2.0.50727"
    Location: "D:\Wood\Visual Studio\Solid Explorer\Solid Explorer\bin\Debug\Solid Explorer.exe"
    ManifestModule: {System.Reflection.Module}
    ReflectionOnly: False
? class_name
"Solid Explorer.frm_Junk"
? form_open
Nothing

So, form_Open doesn't appear to contain anything.  The results are the same, regardless of what form name I use.

Sooo close....
0
 
lofCommented:
ok, i see... IsMdiParent was my mistake, sorry. I meant IsMdiContainer.
Please check the class name.
check what GetType(frm_Junk).FullName is and make sure class_name is set to exactly the same string.

for testing you may do:

class_name = GetType(frm_Junk).FullName 'there is no quotation marks as it is name of the class not literal.

But now i think the problem is with the space in the namespace. I never tried using one and I think it is not allowed.
0
 
lofCommented:
In VB.Net you usually don't have namespaces specified in files so it should be easy to change default name space in project properties to something without a space like SolidExplorer
0
 
CIW_GeorgeAuthor Commented:
Sorry about the delay getting back to y'all.

I changed the namespace to "Solid_Explorer".  Now we're back to about six posts ago, where I never hit the Stop  (12/21/09, 9:45 AM).  At least this confirms that VB doesn't like the space (my fault to start with...) and that we're getting a valid form_Open reference.

Somehow, we've got to be able to define form_Open without actually opening the form until we're ready.  Although I can move the 'Dim form_Open as From =' line further down in the procedure to process the For...Each loops, the procedure will still never hit the last two lines that are needed to make it a MdiChild:

        form_Open.MdiParent = Me
        form_Open.Show()

?????
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 10
  • 9
Tackle projects and never again get stuck behind a technical roadblock.
Join Now