4

In the posted question: "Check if form is opened" the answer below was posted as correct. However, I would like to know how to check if a particular instance of a form is open before opening it; for example, to check if an editing screen of the same record is being opened again, or a form to add a new record, when another form to do the same thing is open already.

Below is the code posted as the correct answer for the original question. Can it be modified to do what I need? Thanks in advance.

If Application.OpenForms().OfType(Of Form2).Any Then

  MessageBox.Show ("Opened")

Else

  Dim f2 As New Form2

  f2.Text = "form2"

  f2.Show()

End If

A particular instance would be a form that is editing a particular record from a table. I would also be tracking the status of the edit (whether the form was in edit mode or not) Or, if this form has a child (a form that edits a sub table of this record); the parent form cannot exit until the child is closed.

I currently create a tree of open forms, their name, the record they are editing, and the edit status, and their closing is updated in the tree. Answer # 2 at first glance seems like it could handle these situations and there would be no need to have this data structure in the background that needs to be constantly updated whenever an action is taken. It might be possible to make it more general so it could be reused easily from application to application.

smh
  • 265
  • 2
  • 5
  • 10
  • What do you mean by a particular instance? How will you distinguish between one instance or another? – Andy G Jul 27 '13 at 20:31
  • Before you commit to doing it this way, be sure to read [this question](http://stackoverflow.com/questions/3751554/application-openforms-count-0-always). Just store the instance of the form in a List so you don't need help finding it back later. – Hans Passant Jul 28 '13 at 11:34

5 Answers5

3

Yes, this can easily be modified to do what you are looking for.

You need to add a public property called Key (or whatever you want) to Form2 and then you can use the ShowOrOpenForm method below to accomplish your goals:

Public Sub ShowOrOpenForm(sKey As String)

    If ShowFormForKey(sKey) Then
        MessageBox.Show("Opened")
    Else
        Dim f2 As New Form2

        f2.Key = sKey
        f2.Text = "form2"
        f2.Show()
    End If
End Sub

Private Function ShowFormForKey(sKey As String) As Boolean

    For Each oForm As Form2 In Application.OpenForms().OfType(Of Form2)()
        If oForm.Key = sKey Then
            oForm.Show()
            Return True
        End If
    Next

    Return False
End Function
competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • This is a good start, I think, to developing a method to track forms. It is unfortunate that the move from vb6 to .net removed the ability to track the opening of forms. I have yet to find anything that corresponds to that but I would like to find something that is simpler than what I am doing now. – smh Jul 29 '13 at 01:52
0

The parent of your editing screen should store information about its current editing screen. If Nothing, no editing screen is open. If non-Nothing, it's set to the current editing screen. In this case you don't need the headache of dealing with OpenForms.

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
  • Yes, thank you. that will prevent an error if it is checked to see if the form is open. – smh Jul 29 '13 at 01:50
0

I could find no property of a VB.Net Form that reliably indicates that the Form has been shown and still has not been Disposed. A disappointment, as @smh says. My solution was along the lines of the suggestion by @Hans Passant: "keep a List", though I use a Collection. @Hans Passant suggested another post but it is a C# Post. Here is the code to manage Forms after Show and before Close or Dispose in Visual Basic:

In use, I call SetOpenForm when creating a New Form, RemoveOpenForm when closing a Form (or when Accept on the Form is Clicked). Between those two Events, the Form and all its data can be retrieved using GetOpenForm & the Form's name. It is valid where only one instance of each Form is open at a time.

Public Shared cOpenForms As Collection  'Place this at the top of your
                                        'set of Forms, e.g. in your MyApp Class.
cOpenForms = New Collection             'Place this in the load sequence of MyApp.

Public Shared Sub SetOpenForm(NamedForm As Form)
    'Saves an Open Form in the Collection of Open Forms
    'Call this every time a New Form is created (if you want to revisit it).
    MyApp.cOpenForms.Add(NamedForm)
End Sub

Public Shared Sub RemoveOpenForm(NamedForm As Form)
    'Removes an Open Form in the Collection of Open Forms, if it is present.  
    'Silently ignores Forms that are not in the Collection.
    'Call this every time a Form is finished with, Closed, Disposed.
    If Not IsNothing(NamedForm) Then
        If MyApp.cOpenForms.Contains(NamedForm.Name) Then
            MyApp.cOpenForms.Remove(NamedForm.Name)
    End If
End Sub
Public Shared Function GetOpenForm(FormName As String) As Form
    'Retrieves a Form if it is in the Collection of Open Forms
    'Call this to retrieve Form FormName; then check for IsNothing.
    For Each f As Form In MyApp.cOpenForms
        If f.Name = FormName Then
            Return f
        End If
    Next
    Return Nothing
End Function
Neil Dunlop
  • 387
  • 3
  • 16
0
 Dim frm2 As New form2

    If isFormNotOpened(frm2) Then
        frm2.Show()
    End If

Private Function isFormNotOpened(ByVal ThisFrm As Form) As Boolean

    Dim xfrm As Form

    isFormNotOpened = True

    For Each xfrm In Application.OpenForms

        If xfrm.Name = ThisFrm.Name Then

            MsgBox(" !!! Already Opened !!! ", MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation)
            xfrm.Activate()

            isFormNotOpened = False
            Exit Function

        End If
    Next


End Function
Julian
  • 33,915
  • 22
  • 119
  • 174
0

You don't need to make a property of the form, and then write/use a method which checks for a key. All you need to do is instantiate the form using an e.g. alias name "frm", and then check if the form is open or not based on the real form name. If it's not open, then invoke .Show()

'instantiate the form, but do not show it (.Show)
Dim frm As MyForm = New MyForm

'test if MyForm.Show was already used (i.e., form is loaded)
Dim frmisopen As Boolean = False
For Each frm As Form In Application.OpenForms
  If frm.Name = "MyForm" Then
    frmisopen = True
  End If
Next

'if form is not loaded, then load it using .Show
If frmisopen = False Then frm.Show()