emub
asked on
Removing form object from a 'collection' when closed
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(iRecordTo Open)
oNewForm.StartPosition = FormStartPosition.CenterSc reen
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad d(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=
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(iRecordTo
oNewForm.StartPosition = FormStartPosition.CenterSc
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad
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=
sorry this should be
CType(Me.Owner, Frmmain).oform.Remove(Me.N ame)
CType(Me.Owner, Frmmain).oform.Remove(Me.N
Djees, whats wrong with my typing
CType(Me.Owner, Frmmain).oFormCollection.R emove(Me.N ame)
CType(Me.Owner, Frmmain).oFormCollection.R
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.
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.
ASKER
bLoadNewForm is Declared everytime the
"Private Sub listmenu_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DoubleClick"
is called.
"Private Sub listmenu_DoubleClick(ByVal
is called.
ASKER
Ok sorry, I forgot to add that
Dim oNewForm As New frmDisplayRecord(iRecordTo Open)
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(By Val sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
CType(Me.Owner, frmMain).oFormCollection.R emove(Me.N ame)
End Sub
As I would get the following message "Type 'frmMain' is not defined."
Dim oNewForm As New frmDisplayRecord(iRecordTo
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(By
CType(Me.Owner, frmMain).oFormCollection.R
End Sub
As I would get the following message "Type 'frmMain' is not defined."
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
is called.
And add
bLoadNewForm(Form_Record_O
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!
if you reference that project in your dll you could
ASKER
Is there anyway to go though the forms objects in the collection and test if they have been closed or not?
ASKER
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?
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(iRecordToOpe n) '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(iRecordTo Open)
oNewForm.StartPosition = FormStartPosition.CenterSc reen
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad d(oNewForm )
End If
use this code:
dim boolean iRecordToOpen(iRecordToOpe
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(iRecordTo
oNewForm.StartPosition = FormStartPosition.CenterSc
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad
End If
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
:) 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(iRecordT oOpen) Then 'If the form isnt already open then open it and add it to the form collection
Dim oNewForm As New frmDisplayRecord(iRecordTo Open)
oNewForm.StartPosition = FormStartPosition.CenterSc reen
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad d(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.
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
Dim iRecordToOpen As Integer
iRecordToOpen = '// Code to get ID of record from listviewitem
If Not IsFormAlreadyOpen(iRecordT
Dim oNewForm As New frmDisplayRecord(iRecordTo
oNewForm.StartPosition = FormStartPosition.CenterSc
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad
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.
Sorry I posted my code not quite correct:
use these codes:
> Define this var 'global' (outside a sub):
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -
dim boolean iRecordToOpen(iRecordToOpe n) '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(iRecordTo Open)
oNewForm.StartPosition = FormStartPosition.CenterSc reen
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad d(oNewForm )
End If
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -
Try it and maybe you like it!
use these codes:
> Define this var 'global' (outside a sub):
--------------------------
dim boolean iRecordToOpen(iRecordToOpe
--------------------------
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(iRecordTo
oNewForm.StartPosition = FormStartPosition.CenterSc
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad
End If
--------------------------
Try it and maybe you like it!
ASKER
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)
"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)
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(iRecordT oOpen) 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.Re move( 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(iRecordTo Open)
oNewForm.StartPosition = FormStartPosition.CenterSc reen
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad d(oNewForm )
End If
End Sub
-------------------------- -----
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
Dim iRecordToOpen As Integer
iRecordToOpen = '// Code to get ID of record from listviewitem
If Not IsFormAlreadyOpen(iRecordT
'Try first to close the form: even when its not open:
Try
frmMain.oFormCollection.Re
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(iRecordTo
oNewForm.StartPosition = FormStartPosition.CenterSc
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad
End If
End Sub
--------------------------
ASKER
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.ObjectDisposedExce ption: 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.
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.ObjectDisposedExce
This is trapped, but the problem now lies with trying to find and remove that closed FORM from collection.
ASKER
Daniellus83: that would work but the problem im having is using the "frmMain.oFromCollection.R emove(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?
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?
ASKER
ik this was fixed by
When adding an item to the collection I changed the code to
frmMain.oFormCollection.Ad d(oNewForm , RecordID)
and when removing the "closed" form I used
frmMain.oFormCollection.Re move(Recor dID)
When adding an item to the collection I changed the code to
frmMain.oFormCollection.Ad
and when removing the "closed" form I used
frmMain.oFormCollection.Re
ASKER
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.
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.
Yes,...
thats it!... I was just reproducing the problem with some buttons,.. it worked and mine is not neccesary any more.
:-\
thats it!... I was just reproducing the problem with some buttons,.. it worked and mine is not neccesary any more.
:-\
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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!
> 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!
ASKER
hehe Wish it would "learn" alittle quicker :)
ASKER
An Array of all RecordID's open?
change
If bLoadForm Then
Dim oNewForm As New frmDisplayRecord(iRecordTo
oNewForm.StartPosition = FormStartPosition.CenterSc
oNewform.owner = me
oNewForm.TopMost = True
oNewForm.Focus()
frmMain.oFormCollection.Ad
End If
in the closed event of your frmdisplayRecord add this
Private Sub frmDisplayRecord_Closed(By
CType(Me.Owner, Form1).oform.Remove(Me.Nam
End Sub