Referencing an running instance of a form(VB6 equiv: loop through the Forms collec.)

  • Thread starter Thread starter Andrejko
  • Start date Start date
A

Andrejko

Guest
Since the Forms collection no longer exists in VB.NET, how do you determine whether a form is already running?
In other words, what is the .NET equivalent of the following VB6 code:

Sub CheckFormStatus(ByRef f As System.Windows.Forms.Form)
Dim I As Short
For I = 0 To Forms.Count - 1
If Forms(I).Tag = f.Tag Then
'this window is already loaded - check if minimized
If Forms(I).WindowState = 1 Then
f.WindowState = System.Windows.Forms.FormWindowState.Normal
End If
Exit For
End If
Next I
f.BringToFront()
End Sub
 
a) That's not VB6 code.
b) You don't.

You write code to keep track of what forms are loaded yourself. VB6 implicitly created an instance of a form with the same name as the form class itself, which led to laziness with some programmers. You should keep track yourself of the instances of forms loaded.
 
You are right

Actualy, you are right. That is a funky mix of VB6 and VB.NET that was generated when I ran the Upgrade Wizard.

Your suggested solution makes perfect sense (to a Java programmer like me, at least ;), and I would gladly go down that route if I were developing a project from scratch. Unfortunately, I am dealing with a rather large VB6 app that needs to become a rather large VB.NET app in less than a month :)

I was just wondering whether there was an easy way of simulating the aforementioned functionality in .NET (without implementing my own Forms collection)

I did come up with a potential solution of my own:
Create a Shared (static in C#) member, similar to DefInstance, called isRunning (or something to that effect) which would be inside each form in the application. Any thoughts?
 
There is no forms collection in .net. Microsoft suggest you subclass the collection class and create your own custom forms collection. Every time you create a reference to a form you would add it to your collection which at any time would ideally return a reference to that form object.
 
You could have a global collection in your project, and inside the constructor of each form you could add the instance to it.
 
divil said:
You could have a global collection in your project, and inside the constructor of each form you could add the instance to it.

You mean a reference, i take it?
In .NET, there is no such thing as global variables. And if it was global, individual forms would not need a reference. But I understand what you mean. Going back to my original post:

Originally posted by Andrejko
I was just wondering whether there was an easy way of simulating the aforementioned functionality in .NET (without implementing my own Forms collection)

And:

Originally posted by Andrejko
I did come up with a potential solution of my own:
Create a Shared (static in C#) member, similar to DefInstance, called isRunning (or something to that effect) which would be inside each form in the application. Any thoughts?
 
Create a module, and make a public collection variable in there to hold all form instances. That is, to all intents and purposes, a global variable. This is a working solution, I've tried it.
 
easy, elegant solution [attempt]

Here is an implementation of the solution I mentioned before:

Code:
#Region "AK: Forms Collection workaround (detecting whether a form is instantiated - 'running')"
    Private Shared m_akIsInstantiated As Boolean = False
    Public Shared Property isInstantiated() As Boolean
        Get
            If m_vb6FormDefInstance Is Nothing OrElse m_vb6FormDefInstance.IsDisposed Then
                m_akIsInstantiated = False
            Else
                m_akIsInstantiated = True
            End If
            isInstantiated = m_akIsInstantiated
        End Get
        Set(ByVal Value As Boolean)
            m_akIsInstantiated = Value
        End Set
    End Property
#End Region
#Region "AK: Modified Upgrade Support "
    Private Shared m_vb6FormDefInstance As Form2
    Private Shared m_InitializingDefInstance As Boolean
    Public Shared Property DefInstance() As Form2
        Get
            If m_vb6FormDefInstance Is Nothing OrElse m_vb6FormDefInstance.IsDisposed Then
                m_InitializingDefInstance = True
                m_vb6FormDefInstance = New Form2()
                m_InitializingDefInstance = False
            End If
            DefInstance = m_vb6FormDefInstance
        End Get
        Set(ByVal Value As Form2)
            m_vb6FormDefInstance = Value
        End Set
    End Property
#End Region

This code goes inside the Public Sub New()
Code:
'### AK: code for IsInstantiated member - see AK: Forms Collection workaround Region 
        m_akIsInstantiated = True

        If m_vb6FormDefInstance Is Nothing Then
            If m_InitializingDefInstance Then
                m_vb6FormDefInstance = Me
            Else
                Try
                    'For the start-up form, the first instance created is the default instance.
                    If System.Reflection.Assembly.GetExecutingAssembly.EntryPoint.DeclaringType Is Me.GetType Then
                        m_vb6FormDefInstance = Me
                    End If
                Catch
                End Try
            End If
        End If

Now, to check whether a form is already instantiated, just do
MyForm.IsInstantiated()
.
Caveat:
This code works in debug mode, but fails whan actually running it. I am currently debugging it, and will post a working solution as soon as I have one.
Does anyone see why this would be failing outside of debug mode?
 
divil said:
Create a module, and make a public collection variable in there to hold all form instances. That is, to all intents and purposes, a global variable. This is a working solution, I've tried it.

I know that the solution you are proposing is a working one. I am not disputing that, as I have said in my previous posts. I am asking for a simpler, quicker solution (like the one I posted above).
 
Back
Top