Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CF- IndexOutOfRange Deleting Row In DataGrid 1

Status
Not open for further replies.

hitechboy78737

Programmer
Nov 8, 2004
82
US
When deleting a single row from a CF datagrid, I get the following error:

"IndexOutOfRangeException Index 2 is not non-negative and below the total rows count"

When I delete ALL the rows, I do not get this error.

I understand WHAT the error is saying, and I think I understand WHY it is thrown... but I'm at a loss how to avoid it.

Following is the code that throws the error:
Code:
  Private Sub mnuDeleteSelected_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuDeleteSelected.Click
        Try

            'get selected row index
            Dim selIndex As Integer = dg1.CurrentRowIndex

            If selIndex > -1 Then

                'remove the row from the row collection
                objGlobal.workingDataTable.Rows.RemoveAt(dg1.CurrentCell.RowNumber)

                'update xml
                objData.saveDataTableToXML()

            End If


        Catch ex As Exception
            objGlobal.showError(ex)
        End Try
    End Sub

Thanks once again for your help!


Kevin Howell
Briefcase of Talent- Austin, Texas
 
Exactly which line is throwing the error? Does this error occur when you delete any row, or does it occur when you delete the last row?


I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson
 
objGlobal.workingDataTable.Rows.RemoveAt(dg1.CurrentCell.RowNumber)"
throws the error.

It errors on any row... but the index number reported in the error is different

I have also used this line:

"objGlobal.workingDataTable.Rows.RemoveAt(selIndex)" which throws the exact same error.



Kevin Howell
Briefcase of Talent- Austin, Texas
 
And objGlobal.workingDataTable is the datasource for the datagrid?

Have you considered using a CurrencyManager and a DataRowView to do the delete? Try this:

Code:
'make the CurrencyManager global, so it can be accessed in different subs/functions

Dim cm as CurrencyManager

'Set the CurrencyManager [red]after[/red] you bind the datasource to the DataGrid

cm = dg1.BindingContext(objGlobal.workingDataTable)

'note: this assumes that objGlobal.workingDataTable is the datasource of the datagrid

'now, when you click on the datagrid, the currencymanager automatically reflects the currently selected row in the datatable

'One other note...for this to work you need to select the
'entire row in the datagrid, just like if you clicked on the
'row header in the grid.

  Private Sub mnuDeleteSelected_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuDeleteSelected.Click
        Try

            'select the entire row
            dg1.Select(dg1.CurrentCell.RowNumber)

            'get the selected row in the datatable
            Dim drv as DataRowView
 
            drv = CType(cm.Current, DataRowView)

            'remove the row from the table
            drv.Delete()

            'update xml
            objData.saveDataTableToXML()


        Catch ex As Exception
            objGlobal.showError(ex)
        End Try
    End Sub

An advantage of using a CurrencyManager in this fashion is that you will get the correct row even if the datagrid is sorted differently from the underlying datatable. That is, if the datagrid is sorted and you select row 2, that may actually be row 43 in the datatable, and when you delete row 2 you have just deleted the wrong row.

Give this a try and let me know if it works out.

BTW - I noticed from your signature that you are located in Austin. So am I! Small world. :)

I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson
 
I get the "option strict disallows implicit conversions from system.windows.forms.bindingmangerbase to system.windows.forms.currencymanager" error on the line

cm = dg1.BindingContext(objGlobal.workingDataTable)


Should I use CType? What am I converting to?

Thanks!


Kevin Howell
Briefcase of Talent- Austin, Texas
 
I took a wild uneducated stab and converted to a currency manager...

But I also get a "System.ObjectDisposedException" on the line:

drv.delete

This really confuses me... I don't think I really understand what the currency manager is doing.

Kevin Howell
Briefcase of Talent- Austin, Texas
 
The currencymanager basically is providing a link between the datagrid and the datasource.

Try making the datarowview global as well.

I used the following code to create a simple datatable, bind a datagrid to it, and then delete rows using the currencymanager/datarowview combination:

Option Strict On

Public Class Form1
Inherits System.Windows.Forms.Form
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu

Dim dt As DataTable
Dim cm As CurrencyManager

#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)
MyBase.Dispose(disposing)
End Sub

'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.
Private Sub InitializeComponent()
Me.MainMenu1 = New System.Windows.Forms.MainMenu
Me.Button1 = New System.Windows.Forms.Button
Me.DataGrid1 = New System.Windows.Forms.DataGrid
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(8, 8)
Me.Button1.Size = New System.Drawing.Size(96, 24)
Me.Button1.Text = "Button1"
'
'DataGrid1
'
Me.DataGrid1.Location = New System.Drawing.Point(0, 64)
Me.DataGrid1.Size = New System.Drawing.Size(240, 200)
Me.DataGrid1.Text = "DataGrid1"
'
'Form1
'
Me.Controls.Add(Me.DataGrid1)
Me.Controls.Add(Me.Button1)
Me.Menu = Me.MainMenu1
Me.Text = "Form1"

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer

SetUpTable()

Dim dr As DataRow

For i = 0 To 5
dr = dt.NewRow

With dr
.Item(0) = "Data " & i.ToString
.Item(1) = "Data " & i.ToString
dt.Rows.Add(dr)
dr = Nothing

End With
Next

DataGrid1.DataSource = dt

cm = CType(DataGrid1.BindingContext(dt), CurrencyManager)

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'select the entire row
DataGrid1.Select(DataGrid1.CurrentCell.RowNumber)

'get the selected row in the datatable
Dim drv As DataRowView

drv = CType(cm.Current, DataRowView)

'remove the row from the table
drv.Delete()
End Sub

Private Sub SetUpTable()
Dim dc1 As DataColumn
Dim dc2 As DataColumn

dc1 = New DataColumn("Col1")
dc1.DataType = System.Type.GetType("System.String")

dc2 = New DataColumn("Col2")
dc2.DataType = System.Type.GetType("System.String")

dt = New DataTable

dt.Columns.Add(dc1)
dt.Columns.Add(dc2)

End Sub

End Class

I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson
 
I'm back to working on this project... and STILL can't figure out what I'm doing wrong.

I have made the currency manager & datarowview global

I set the currency manager in the form load after the binding:

Code:
dg1.DataSource = objGlobal.workingDataTable

objCM = CType(dg1.BindingContext(objGlobal.workingDataTable), CurrencyManager)

Then I do this:
Code:
    Private Sub mnuDeleteSelected_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuDeleteSelected.Click
        Try

            'get selected row index
            Dim selIndex As Integer = dg1.CurrentRowIndex
            If selIndex > -1 Then

                'select the entire row
                dg1.Select(dg1.CurrentCell.RowNumber)

                'get the selected row in the datatable
                drv = CType(objCM.Current, DataRowView)


                'remove the row from the table
                drv.Delete()

                'update xml
                objData.saveDataTableToXML()

            End If

        Catch ex As Exception
            objGlobal.showError(ex)
        End Try
    End Sub

When it gets to the "drv.delete" line it errors with

"System.ObjectDisposedException"

What is weird is if I continue on (not click "break") it actually removes the row. So it's working its just bitching about it.

Is this normal?

Thanks for hammering on this with me!


Kevin Howell
Briefcase of Talent- Austin, Texas
 
I'm stumped. Without seeing all of your code, I cannot determine what object is disposed that might be affecting the delete with the datarowview.

Did you try running the code I posted, that creates a simple datatable and displays it in a datagrid? If you do run it, do you get the same error when you do the delete? Is there any more text in the error message, such as the type of object that is causing the error?

Could I contact you via your website, and perhaps you could email me the project files and I could take a look at them?


I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson
 
This is for a handheld, PPC 2002. Perhaps that makes a difference? It is a CF datagrid, not the usual VB datagrid

The error is happening in system.windows.forms

You can contact me at kevin.howell@athletics.utexas.edu

I'm seriously thinking about elimating that function from the feature set... I can't really think of a legitimate reason the user should delete one record... or maybe I'm just justifying my failure? <g>





Kevin Howell
Briefcase of Talent- Austin, Texas
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top