[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Removing form object from a 'collection' when closed

Posted on 2004-08-11
25
Medium Priority
?
349 Views
Last Modified: 2008-03-10
Hi,

Im having a little problem with forms :)

Basicly, I have a listview of records and when a user dbl click's a record it opens a new instance of the displayrecord form.  The user can open multiple records but if a use tries to open record for which they already have the form open it will just brings the existing open form to focus (I store he record ID in the .TAG so I know which form is for which record)

Now everything works great inc bring the already existing form to focus, apart from when I close a form it dosnt get removed from the collection object that stored all the forms so I cant reopen a record after its closed.

I've inc'd some code to hopfully make it clear how im doing it.

[Main Form (frmMain) With Listview on it]
Friend Shared oFormCollection as New Collection

[In Listview dblClick Code]
'// Before loading form lets make sure it isnt already open
Dim iRecordToOpen As Integer

iRecordToOpen = '// Code Here

Dim oForm As Form
Dim bLoadNewForm As Boolean = True

For Each oForm In frmMain.oFormCollection
      If oForm.Tag = iRecordToOpen Then
           oForm.BringToFront()
           oForm.Focus()
           bLoadNewForm = False
           Exit For
      End If
Next

'// If form isnt open then create a instance of the record form and display it
If bLoadNewForm Then
      Dim oNewForm As New frmDisplayRecord(iRecordToOpen)
      oNewForm.StartPosition = FormStartPosition.CenterScreen
      oNewForm.TopMost = True
      oNewForm.Focus()
      frmMain.oFormCollection.Add(oNewForm)
End If

[END]

It apears when I close the form, the instance of the form object stays in the oFormCollection, which mean if I wish to reopen the record it already thinks is open.  Am I going about this the wrong way?

Regards

=Daniel=
0
Comment
Question by:emub
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 12
  • 8
  • 5
25 Comments
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 11772253

change

If bLoadForm Then
      Dim oNewForm As New frmDisplayRecord(iRecordToOpen)
      oNewForm.StartPosition = FormStartPosition.CenterScreen
      oNewform.owner = me
      oNewForm.TopMost = True
      oNewForm.Focus()
      frmMain.oFormCollection.Add(oNewForm,oNewform.Name)
End If

in the closed event of your frmdisplayRecord add this

    Private Sub frmDisplayRecord_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        CType(Me.Owner, Form1).oform.Remove(Me.Name)
    End Sub

0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 11772267
sorry this should be

 CType(Me.Owner, Frmmain).oform.Remove(Me.Name)
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 11772278
Djees, whats wrong with my typing

CType(Me.Owner, Frmmain).oFormCollection.Remove(Me.Name)

0
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.

 
LVL 4

Expert Comment

by:Daniellus83
ID: 11772321
If I am understanding it all well:

you forgot to add this code

      bLoadNewForm = True

You should add this code inside the "Closing" (or something) event/handle of the opened Form. Thats why it thinks that its still open. So, as soon as that form is closed, its putting the boolean var bLoadNewForm back to value True.

0
 

Author Comment

by:emub
ID: 11772419
bLoadNewForm is Declared everytime the

"Private Sub listmenu_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DoubleClick"

is called.
0
 

Author Comment

by:emub
ID: 11772496
Ok sorry, I forgot to add that  

Dim oNewForm As New frmDisplayRecord(iRecordToOpen)

frmDisplayRecord(ByVal RecordID As Integer) Is a function that reutrns a form from another DLL.  So effectivly the form DisplayRecord isnt in the same project

( Sorry I should have mentioned that )

So If couldnt put

    Private Sub frmDisplayRecord_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        CType(Me.Owner, frmMain).oFormCollection.Remove(Me.Name)
    End Sub

As I would get the following message "Type 'frmMain' is not defined."

0
 
LVL 4

Expert Comment

by:Daniellus83
ID: 11772550

Ow, I understood that you have multiple forms open. Don't you need also multiple var bLoadNewForm. Like an array of bLoadNewForm(1 to Max Number of possible WindowWith_Record Open)?

Then you should get rid of this:


       bLoadNewForm is Declared everytime the

       "Private Sub listmenu_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DoubleClick"

       is called.


And add
     
      bLoadNewForm(Form_Record_Open_ID) = True

       You should add this code inside the "Closing" (or something) event/handle of the opened Form. Thats why it thinks that its still open.
       So, as soon as that form is closed, its putting the boolean var bLoadNewForm back to value True.

For every possible open form!
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 11772552
if you reference that project in your dll you could
0
 

Author Comment

by:emub
ID: 11772565
Is there anyway to go though the forms objects in the collection and test if they have been closed or not?
0
 

Author Comment

by:emub
ID: 11772640
The frmMain is in the Main EXE,   frmDisplayRecord is in a seperate DLL, I presumed in the DLL you can only reference to other DLL not EXE's?
0
 
LVL 4

Expert Comment

by:Daniellus83
ID: 11772651
Okay,.. you need to find first out if this form is open (after the user clicked a record on the listview):

use this code:

dim boolean iRecordToOpen(iRecordToOpen)   'I assume this var has number 1 to 100 or so...


For Each oForm In frmMain.oFormCollection
      If oForm.Tag = iRecordToOpen Then
           oForm.BringToFront()
           oForm.Focus()
           bLoadNewForm = False
           Exit For
      End If
      '
      'If the user gets here, the form isn't open (yet)!
      'Set Boolean to True
     bLoadNewForm (iRecordToOpen) = True
Next


Now execute the following code:


If bLoadNewForm (iRecordToOpen) Then
      Dim oNewForm As New frmDisplayRecord(iRecordToOpen)
      oNewForm.StartPosition = FormStartPosition.CenterScreen
      oNewForm.TopMost = True
      oNewForm.Focus()
      frmMain.oFormCollection.Add(oNewForm)
End If


0
 
LVL 25

Accepted Solution

by:
RonaldBiemans earned 1600 total points
ID: 11772884
you could do this ofcourse

        For Each oForm2 In oform
            Try
                oForm2.Select()
            Catch EX As Exception
                oform.Remove(oForm2.Name)
            End Try
        Next

0
 

Author Comment

by:emub
ID: 11773030
:) I thinks there has been some crossed wires with the var bLoadNewForm, this was tempoary var I was using that was onyl referenced during the dbl_click process (my fault its was poorly written)

I restructurd the code to make it clear (even though the problem still exists) :) hehe

[on the main form]

Dim oFormCollection As New Collection     '// This hold a collection of all the forms that are open

[on the doubleclick part of the list view]

Private Sub listmenu_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DoubleClick
      Dim iRecordToOpen As Integer
     
      iRecordToOpen =  '// Code to get ID of record from listviewitem

      If Not IsFormAlreadyOpen(iRecordToOpen) Then    'If the form isnt already open then open it and add it to the form collection
            Dim oNewForm As New frmDisplayRecord(iRecordToOpen)
            oNewForm.StartPosition = FormStartPosition.CenterScreen
            oNewForm.TopMost = True
            oNewForm.Focus()
            frmMain.oFormCollection.Add(oNewForm)
      End If
End Sub

[function within the listview]

Private Function IsFormAlreadyOpen(byVal RecordID As Integer) As Boolean
      Dim oForm As Form

      For Each oForm In frmMain.oFormCollection
            If oForm.Tag = RecordID Then
                 oForm.BringToFront()
                 oForm.Focus()
                 Return True
            End If
      Next

     '// If code should reach here then the record isnt already open
     Return False
End Function


[END]

Now when I close a record form, the instace of the object is still in the oFormCollection so when the function IsFormAlreadyOpen() is call it find the relevant form and tries to bring it to focus then returns True. How ever the user as already closed this form.
0
 
LVL 4

Expert Comment

by:Daniellus83
ID: 11773031
Sorry I posted my code not quite correct:

use these codes:

> Define this var 'global' (outside a sub):

-----------------------------------------------------------------------------------------------------------------------------------------

dim boolean iRecordToOpen(iRecordToOpen)   'I assume this var has number 1 to 100 or so...

-----------------------------------------------------------------------------------------------------------------------------------------

You need a boolean var for each possible form with record information.



> Put this piece of code in the Event thats called (OnDoubleClick?) of your ListView:

-----------------------------------------------------------------------------------------------------------------------------------------
'First we need to check if this form with clicked record is already open:

For Each oForm In frmMain.oFormCollection
      If oForm.Tag = iRecordToOpen Then
           oForm.BringToFront()
           oForm.Focus()
           bLoadNewForm = False
           Exit For
      End If
      '
      'If the user gets here, the form isn't open (yet)!
      'Set Boolean to True
     bLoadNewForm (iRecordToOpen) = True

Next

'If this Form is not found, the For-loop finish with the bLoadNewForm (iRecordToOpen)  set to  TRUE.
'If that is so, we have to generate the form and open it:

If bLoadNewForm (iRecordToOpen) Then
      Dim oNewForm As New frmDisplayRecord(iRecordToOpen)
      oNewForm.StartPosition = FormStartPosition.CenterScreen
      oNewForm.TopMost = True
      oNewForm.Focus()
      frmMain.oFormCollection.Add(oNewForm)
End If

-----------------------------------------------------------------------------------------------------------------------------------------


Try it and maybe you like it!
0
 

Author Comment

by:emub
ID: 11773206
RonaldBiemans: I tried that but get the following error when trying to remove the "closed" form from the collection

"Additional information: Argument 'Key' is not a valid value."


 Daniellus83: With using an array, I would need to know how many record would be in the listview so I can declarer it? (I think)
0
 
LVL 4

Expert Comment

by:Daniellus83
ID: 11773275
Why not try to remove the form first?!

In the case the window is already open: the user wouldn't see it if it was already open:

Change this code:

-------------------------------

Private Sub listmenu_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DoubleClick
      Dim iRecordToOpen As Integer
     
      iRecordToOpen =  '// Code to get ID of record from listviewitem

      If Not IsFormAlreadyOpen(iRecordToOpen) Then    'If the form isnt already open then open it and add it to the form collection

           'Try first to close the form: even when its not open:

             Try
                frmMain.oFormCollection.Remove( THE_FORM_iRecordToOpen)
             Catch EX As Exception
                'The code here would be called if the form couldn't be closed,.. just don't put here any code!
            End Try
     
            Dim oNewForm As New frmDisplayRecord(iRecordToOpen)
            oNewForm.StartPosition = FormStartPosition.CenterScreen
            oNewForm.TopMost = True
            oNewForm.Focus()
            frmMain.oFormCollection.Add(oNewForm)
      End If
End Sub

-------------------------------

   
0
 

Author Comment

by:emub
ID: 11773312
RonaldBiemans:  

That idea seems to be along the right path, as the form object once its is closed still remains the the oFromCollection in a "disposed" state, hance its closed but its instance is still there in the collection.
Trying the .Select does cause an error

"System.ObjectDisposedException: Cannot access a disposed object named "UserDetails". Object name: "UserDetails"."

This is trapped, but the problem now lies with trying to find and remove that closed FORM from collection.
0
 

Author Comment

by:emub
ID: 11773419
Daniellus83: that would work but the problem im having is using the "frmMain.oFromCollection.Remove(key as string)" function.

I need to locate the correct form in the collection and remove it, but as far as im aware they are all called the same thing?
0
 

Author Comment

by:emub
ID: 11773487
ik this was fixed by


When adding an item to the collection I changed the code to

frmMain.oFormCollection.Add(oNewForm, RecordID)

and when removing the "closed" form I used

frmMain.oFormCollection.Remove(RecordID)



0
 

Author Comment

by:emub
ID: 11773601
Ok 1 last question regarding Exceptions

I tested this and I get the follow behaviour

Open Record Number 1, For shows
Close Record Number 1 form
Reopen Record Number 1,  there is a very long pause while its at the exception part, then form opens
Close Record Number 1 form
reopen Recrd Number 1, opens instantly

open and close and records repeatly and they open close without delay?

It would seem that when the program runs the first time it encounters the exception its does something (maybe searchs and loads somthing) then once its done it for the first time, after that its runs really smooth.
0
 
LVL 4

Expert Comment

by:Daniellus83
ID: 11773604
Yes,...

thats it!... I was just reproducing the problem with some buttons,.. it worked and mine is not neccesary any more.

:-\
0
 
LVL 4

Assisted Solution

by:Daniellus83
Daniellus83 earned 400 total points
ID: 11773634
I had the same problem,.. that must be it ("the learning process..." ;-) ) I cannot really explain why.. thats something 'deeper'.
0
 
LVL 4

Expert Comment

by:Daniellus83
ID: 11773744
Anyway, I have one (hopefully good suggestion) since the try statement is not the finest to have...

> Why not keep a (global defined) array with opened ID wich are opened. Everytime one is closed, you search this array, if you find it, delete it in the Collection (and delete it in the array)

This way you have taken proper care of the window-management!
0
 

Author Comment

by:emub
ID: 11773746
hehe Wish it would "learn" alittle quicker :)
0
 

Author Comment

by:emub
ID: 11773787
An Array of all RecordID's open?
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Kraeven
Introduction Remote Share is a simple remote sharing tool, enabling you to see, add and remove remote or local shares. The application is written in VB.NET targeting the .NET framework 2.0. The source code and the compiled programs have been in…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question