1

Form Name comes from a variable. I would like to open Form from variable value.

In VBA load("UserFormName") will show the form. But I don't know how to do it in VB.Net.

Sixthsense
  • 1,927
  • 2
  • 16
  • 38
  • When you say `Form Name comes from a variable`, do you mean something like: Dim formToDisplay = New , so that when it comes to compile time, you are not 100% certain which exact form will be needed? – JayV Apr 25 '19 at 11:10
  • Check Activator.CreateInstance() – Leszek P Apr 25 '19 at 11:13
  • 2
    https://www.tek-tips.com/viewthread.cfm?qid=1756182 – Leszek P Apr 25 '19 at 11:16
  • Possible duplicate of https://stackoverflow.com/questions/7598088/purpose-of-activator-createinstance-with-example, though it may not look like it at first glance, and that question is on C#. – MarkL Apr 25 '19 at 13:55
  • See the code that activates a Form by name [here](https://stackoverflow.com/a/55804333/7444103) (first code snippet). It's the `Dim form = CType(Activator.CreateInstance(Type.GetType($"{appNameSpace}.{formName}")), Form)` part. – Jimi Apr 25 '19 at 14:20

3 Answers3

4

Ok, of course one would want to be able to open a form by string name.

When you create a vb.net winforms project, then all forms are available as a "base" static class.

You often see a LOT of code thus simply use the base form class.

If I need to display say form2, then I really don't need to create a instance of that form (unless you want to have multiple instances of that form. So a truckload of code will simply launch + use the "base static" class of that form.

eg:

Form2.Show()

I don't consider this all that bad of a practice, since what do you think the project settings to "set" the startup form in the project settings does?

It simply sets the built in instance of "mainForm" = to your startup form and it does NOT create new instance.

So, now that we all can agree for 15+ years anyone who has set the startup form in their project is NOT creating a NEW instance of that form, but in fact using the base class instance. This is really a programming choice.

So, code to display (show) the base static instance of a form by string name will look like this:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim strForm As String = "Form1"
    ShowFormByName(strForm)

End Sub

Public Sub ShowFormByName(strFormName As String)

    System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(ProductName & "." & strFormName).show()

End Sub


Private Function FormByName(strFormName As String) As Form
    Return System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(ProductName & "." & strFormName)
End Function

However, above includes a helper sub that will simply "show" that built in instance of the forms.

And above also includes a function to return class type of the form, since for sure a good many developers prefer to first create a instance of the form, and then "show()" it.

So, often we do want multiple instances, or we just perfer the codeing approach of creating a new instance of the form object.

So, we use the 2nd helper function to return a form object of the type we passed by string.

So, to display 3 instances of form1, but the FIRST instance being the base class, then two more but brand new instances of that form, we have this code:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim strForm As String = "Form1"
    ShowFormByName(strForm)

    Dim f1 As Form = FormByName(strForm)
    Dim f2 As Form = FormByName(strForm)

    f1.Show()
    f2.Show()

End Sub

So the above code snip shows how to display the built in base class form without having to create a instance of that form.

However, the next two forms we load are "new" instances of that form as "string".

So the helper sub, and helper function will give you both choices as to which preference floats your boat.

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • I would like to invoke built in base class form from variable value. Because the form name comes from my DB which is stored in variable. I decide which form is accessible to which person by taking control of the DB. So I want to invoke the built in base class form by variable value. I don't want the instances of the form. – Sixthsense Apr 26 '19 at 04:28
  • 1
    Right, my example (first one) shows an example of launching the form based on a string - an no new instance is created nor is it required. So, of my two examples - first example does as you ask. So, just call that ShowByName(" your string form name") and it will show/display the form without having to create a instance. I of course included both ways, as it often common to create a instance of the form first - but as the first example code shows you don't need to create a instance - it just shows the given form based on the passed string. – Albert D. Kallal Apr 26 '19 at 07:08
  • I use that code with small changes: System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(My.Application.Info.Title & "." & strFormName).show() – Mehmet Arlı Mar 19 '23 at 14:47
0
Dim form = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(Application.ProductName & "." & MySubForm)
Dim frm As New Form
frm = form
frm.MdiParent = AFrmMainScreen
frm.WindowState = FormWindowState.Maximized
frm.Show()
LarsTech
  • 80,625
  • 14
  • 153
  • 225
MAMPRO
  • 69
  • 6
  • Hellow, "LarsTech" , I am somehow new on "stackoverflow.com", but is it normal to edit someone answers? I mean can you even edit the code answer itself as well? – MAMPRO Apr 26 '19 at 23:43
  • Yes. We prefer not any noise, like "thank you" etc. Just the answer. An explanation of your code might improve it. – LarsTech Apr 26 '19 at 23:45
  • Yes, got it. Thanks for sharing ^_^ – MAMPRO Apr 26 '19 at 23:47
0

I prefer to use Reflection.Assembly.GetEntryAssembly because I use several different projects in one solution. This allows me to put this code in a different project(dll) that has a usercontrol that I can then reuse across multiple solutions. You also don't need to know the "Namespace" for the form as long as it is in the startup project.

The code below gets the form type from the exported types from the entry assembly and then uses Activator.CreateInstance to create a new instance of the form. Then I return that form in the function.

Public Function GetForm(ByVal objectName As String) As Form
    Try
        Dim frmType = Reflection.Assembly.GetEntryAssembly.GetExportedTypes.FirstOrDefault(Function(x) x.Name = objectName)
        Dim returnForm = TryCast(Activator.CreateInstance(frmType), Form)
        Return TryCast(returnForm, Form)
    Catch ex As Exception
        Return Nothing
    End Try
End Function

To use the above function:

Dim MyForm = GetForm(FormLocation)
If MyForm IsNot Nothing Then
    MyForm.ShowDialog()
    'You can do any form manipulation from here.
Else
    MessageBox.Show($"{FormLocation} was not found.")
End If
Nathan
  • 789
  • 11
  • 20