too many form instances...

  • Thread starter Thread starter Jan Nielsen
  • Start date Start date
J

Jan Nielsen

Hi
I have a main form showing personal information (name, address etc.) bound
to a dataset.
One of the pieces of information is the Group the person belongs to. This is
selected from a combo box.
If I want to add a new group to the list. I open a new form like this

myfrmAddGroup = New FrmAddGroup(Me.Dataset1)
myfrmAddGroup.Show()
myfrmAddGroup = Nothing

The FrmAddgroup has this constructor:

Public Sub New(ByRef inpds As Dataset)

It then uses this dataset as datasource in a grid.
No problems this far.

But if I open the form and add a new group.
Then close the form
Then open the form and delete a group. (Any group)
I receive the error:
"An unhandled exception of type 'System.IndexOutOfRangeException' occurred
in system.windows.forms.dll
Additional information: No value at index 13."
In the _main_ forms first line (Public Class frmMainForm) .
And I can´t debug it. It does not say where it appeared. (And I of course
have try catch on all functions)

(I have 14 items in the group list)
I added an rowdeleting eventhandler to frmAddGroup and it appears that this
is called one time for each time I open the form. Ie if open and close the
form 5 times the eventhandler is called 5 times when I delete a row.

So it makes sense: it first deletes the row as it is supposed to. index 13
is fine. But then it tries to delete the row at index 13 again. and fails.
How do get rid of the closed instances of the frmAddGroup so this will not
happen?

Any suggestions?

TIA

Jan
 
Jan,

New FrmAddGroup(Me.Dataset1)
myfrmAddGroup.Show()
myfrmAddGroup = Nothing

When I see this kind of code I think directly on "IsDisposed"

Setting a frm to nothing has no sense by the way, this will be ignored when
there is still a reference to that object.

http://msdn.microsoft.com/library/d...emwindowsformscontrolclassisdisposedtopic.asp

A piece of code from a message from Hefried
\\\\
If foSearchForm Is Nothing OrElse foSearchForm.IsDisposed Then
foSearchForm = New FrmSearchForm()
End If
foSearchForm.Show()
///

I hope this helps?

Cor
 
Hi Cor
Thanks for answering.

I tried Herfrieds code
It does not make any difference.
Remember I close the form (by clicking the red X) then open it, then close
it etc.
This also disposes it. (I have verified this. The Dispose of the form is
executed)

Jan
 
Jan,

A question, is there in your datagrid a comboboxcolumn?

Cor

"Jan Nielsen"
 
Jan,

I do not understand this.
Therefore I added a sample is that something as you are doing this?

\\\form1 with a button
Dim ds As New DataSet
Dim frm As Form2
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
createDS()
frm = New Form2(ds)
frm.Owner = Me
frm.Show()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
ds.Tables(0).Rows(2).Delete()
If frm.IsDisposed Then
frm = New Form12(ds)
frm.Show()
Else
frm.TopMost = True
End If
End Sub
Public Sub createDS()
Dim dt As New DataTable
ds.Tables.Add(dt)
dt.Columns.Add("Numbers", GetType(System.Int32))
dt.Columns.Add("Characters")
For i As Integer = 0 To 9
ds.Tables(0).Rows.Add(ds.Tables(0).NewRow)
ds.Tables(0).Rows(i).ItemArray = _
(New Object() {i.ToString, ChrW(i + 65)})
Next
End Sub
////
\\\Form2 has a datagrid and the form new is like this
Private ds1 As DataSet
Public Sub New(ByVal ds As DataSet)
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
ds1 = ds
'Add any initialization after the InitializeComponent() call
DataGrid1.DataSource = ds1.Tables(0)
End Sub
////

I am curious about that

Cor


"Jan Nielsen"
 
Hi Cor

Form1 code:
*********************************************************************************
Dim ds As New DataSet()
Dim frm As Form2
Dim i As Integer
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
createDS()
End Sub
Public Sub createDS()
Dim dt As New DataTable()
ds.Tables.Add(dt)
dt.Columns.Add("Numbers", GetType(System.Int32))
dt.Columns.Add("Characters")
For i = 0 To 9
ds.Tables(0).Rows.Add(ds.Tables(0).NewRow)
ds.Tables(0).Rows(i).ItemArray = _
(New Object() {i.ToString, ChrW(i + 65)})
Next
End Sub

Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
frm = New Form2(ds)
' frm.Owner = Me
frm.Show()
End Sub
*********************************************************************************

Form2 code (Entire form class):
*********************************************************************************
Public Class Form2
Inherits System.Windows.Forms.Form
Private ds1 As DataSet
#Region " Windows Form Designer generated code "
Public Sub New(ByVal ds As DataSet)
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
ds1 = ds
'Add any initialization after the InitializeComponent() call
DataGrid1.DataSource = ds1.Tables(0)
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.DataGrid1 = New System.Windows.Forms.DataGrid()
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'DataGrid1
'
Me.DataGrid1.DataMember = ""
Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
Me.DataGrid1.Name = "DataGrid1"
Me.DataGrid1.Size = New System.Drawing.Size(264, 256)
Me.DataGrid1.TabIndex = 0
'
'Form2
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.DataGrid1})
Me.Name = "Form2"
Me.Text = "Form2"
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
#End Region
End Class

*********************************************************************************

Now open form2 and add a row
Close form2
Open form2 again and delete the row you just added

Best regards

Jan
 
Jan,

I tested what you sent, however that did not throw an error in the way as
you told it.

Not important, however in my sample is an typor there is on someplaces
form12 what has to be form2 (i changed it in the text)

Cor
 
Hi Cor
Yes, I noticed the form12 thing.
I use VS 2002. Could that be the problem?

Jan

Jan
 
Jan,

I would not know why, I don't have that any more installed.

However would look strange to me, you tested it exactly with that sample
program as you showed me?

(And does the delete just with the delete key)

Cor

"Jan Nielsen"
 
Hi Cor
Here is the exact code for the 2 forms:
Form1:
*****************************************************************
Public Class Form1

Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

Friend WithEvents Button1 As System.Windows.Forms.Button

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.Button1 = New System.Windows.Forms.Button()

Me.SuspendLayout()

'

'Button1

'

Me.Button1.Location = New System.Drawing.Point(88, 56)

Me.Button1.Name = "Button1"

Me.Button1.TabIndex = 0

Me.Button1.Text = "Button1"

'

'Form1

'

Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

Me.ClientSize = New System.Drawing.Size(292, 266)

Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Button1})

Me.Name = "Form1"

Me.Text = "Form1"

Me.ResumeLayout(False)

End Sub

#End Region

Dim ds As New DataSet()

Dim frm As Form2

Dim i As Integer

Private Sub Form1_Load(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles MyBase.Load

createDS()


End Sub


Public Sub createDS()

Dim dt As New DataTable()

ds.Tables.Add(dt)

dt.Columns.Add("Numbers", GetType(System.Int32))

dt.Columns.Add("Characters")

For i = 0 To 9

ds.Tables(0).Rows.Add(ds.Tables(0).NewRow)

ds.Tables(0).Rows(i).ItemArray = _

(New Object() {i.ToString, ChrW(i + 65)})

Next

End Sub



Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

frm = New Form2(ds)

' frm.Owner = Me

frm.Show()

End Sub

End Class

*****************************************************************


Form2:
*****************************************************************
Public Class Form2

Inherits System.Windows.Forms.Form

Private ds1 As DataSet

#Region " Windows Form Designer generated code "

Public Sub New(ByVal ds As DataSet)

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

ds1 = ds

'Add any initialization after the InitializeComponent() call

DataGrid1.DataSource = ds1.Tables(0)

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.DataGrid1 = New System.Windows.Forms.DataGrid()

CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()

Me.SuspendLayout()

'

'DataGrid1

'

Me.DataGrid1.DataMember = ""

Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText

Me.DataGrid1.Name = "DataGrid1"

Me.DataGrid1.Size = New System.Drawing.Size(264, 256)

Me.DataGrid1.TabIndex = 0

'

'Form2

'

Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

Me.ClientSize = New System.Drawing.Size(292, 266)

Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.DataGrid1})

Me.Name = "Form2"

Me.Text = "Form2"

CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()

Me.ResumeLayout(False)

End Sub

#End Region

End Class



*****************************************************************

And here is exact what I do:
I start the program
Then I click Button1
Then I add the values "99", "Testing" to a row. And click with the mouse in
a NEW row to save this row (ie the row with the * to the left). This is very
important for the error to appear. Sorry I forgot to tell that. If you
create the row and click in an old row the error will not appear.
Then I close Form2
Then I open Form2
Then I delete the row with values "99", "Testing" by marking the record
selector with the mouse and pressing the Delete key
Then the error appears

Jan
 
Jan,

Now I could simulate the error,

With adding this the error was gone. I did not test on side effects of
course.
\\\
Private Sub Form2_Closing(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
BindingContext(ds1.Tables(0)).EndCurrentEdit()
End Sub
///

I hope it helps however?

Cor
 
Hi Cor
Thanks for your help
Appearantly it solved the problem
I'll be back

Jan
 
Hi again Cor
As I wrote in my last mail, it solves the problem, but it adds an empty row
(a row with null value) to the datatable.
But I guess I´ll just have to delete all rows with null value when I close
the form.

I still do not understand why the problem occurs.
And I do not understand why I can´t catch it with a try catch

Best regards

Jan
 
Jan,

I am not reproducing your error anymore or read the thread, however was it
not that you created an empty row and than closes when the error did occur.
This kind of behaviour you can prevent by adding an "NewRow" button to your
form and remove the + row with.

table.defaultview.allownew = false

When you than want to add a row you have to set it temporaly to true by the
way.

Just my thought,

Cor
 
Hi again Cor
Thanks for your advice
The error occurred when you
1) added a new row, and
2) clicked with the mouse in the new empty row that appears as soon as you
enter text in the new row.
3) closed the form and re-opened it
4) deleted the newly added row

I´ll look at your solution.
But as far as I can see it will not take me anywhere ;-)
As soon as I allowNew I imagine that the problem appears again.

Best regards

Jan
 
Jan,

Than I remembered me it well,
The error occurred when you
1) added a new row, and
2) clicked with the mouse in the new empty row that appears as soon as you
enter text in the new row.

And here the row will be produced by the endcurrentedit
Because of the fact that you cannot see if the user has entered something or
not when he pushed on the close button you should in my opinion either
checks on null or make this behaviour impossible by deleting the + button.
That is of course your choise.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top