I am using VS 2005 Beta 2 and I'm having a problem removing rows from a DataGridView. The sample code below populates a DataGridView located in an MDI child form with 10 rows. The first three columns of each row contain buttons to Edit, View or Delete a row. The Edit and View buttons work under any circumstance but the Delete operation only works on the first 8 deletes and then when either of the remaining two rows has its Delete button clicked, an exception is thrown.
This behavior is interesting, but what is even more interesting is that if I use the spacebar to select the Delete button then I can remove all rows without an exception being thrown. In other words, I only get the exception when clicking on one of the two rows remaining in the grid. Clicking works on the first 8 clicks of the Delete button.
The exception and the code sample are given below.
Any ideas on why I can delete the last two rows with the spacebar but not with the mouse
Here's the exception:
System.ArgumentOutOfRangeException
Specified argument was out of the range of valid values.
Parameter name: rowIndex
StackTrace:
at System.Windows.Forms.DataGridView.InvalidateCell(Int32 columnIndex, Int32 rowIndex)
at System.Windows.Forms.DataGridViewButtonCell.OnLeave(Int32 rowIndex, Boolean throughMouseClick)
at System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick)
at System.Windows.Forms.DataGridView.OnRemovingRow(Int32 rowIndexDeleted, Point& newCurrentCell, Boolean force)
at System.Windows.Forms.DataGridViewRowCollection.RemoveAtInternal(Int32 index, Boolean force)
at System.Windows.Forms.DataGridViewRowCollection.RemoveAt(Int32 index)
at GridClearTest.ViewForm.deleteRow(Int32 row) in C:\Documents and Settings\ty814c\My Documents\Visual Studio 2005\Projects\GridClearTest\GridClearTest\ViewForm.vb:line 89
at GridClearTest.ViewForm.onButtonCellClick(DataGridViewCellEventArgs e) in C:\Documents and Settings\ty814c\My Documents\Visual Studio 2005\Projects\GridClearTest\GridClearTest\ViewForm.vb:line 82
at GridClearTest.ViewForm.grdTests_CellClick(Object sender, DataGridViewCellEventArgs e) in C:\Documents and Settings\ty814c\My Documents\Visual Studio 2005\Projects\GridClearTest\GridClearTest\ViewForm.vb:line 99
at System.Windows.Forms.DataGridView.OnCellClick(DataGridViewCellEventArgs e)
at System.Windows.Forms.DataGridView.OnMouseClick(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.DataGridView.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at GridClearTest.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 76
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Here's the code for MainForm.designer.vb:
< Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _Partial Public Class MainForm Inherits System.Windows.Forms.Form 'Form overrides dispose to clean up the component list.<System.Diagnostics.DebuggerNonUserCode()> _ Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing AndAlso components IsNot Nothing Thencomponents.Dispose() 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.<System.Diagnostics.DebuggerStepThrough()> _ Private Sub InitializeComponent() Me.MenuStrip1 = New System.Windows.Forms.MenuStrip Me.OpenGridToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem Me.MenuStrip1.SuspendLayout() Me.SuspendLayout() ' 'MenuStrip1 ' Me.MenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.OpenGridToolStripMenuItem}) Me.MenuStrip1.Location = New System.Drawing.Point(0, 0) Me.MenuStrip1.Name = "MenuStrip1" Me.MenuStrip1.Size = New System.Drawing.Size(748, 24) Me.MenuStrip1.TabIndex = 2 Me.MenuStrip1.Text = "MenuStrip1" ' 'OpenGridToolStripMenuItem ' Me.OpenGridToolStripMenuItem.Name = "OpenGridToolStripMenuItem" Me.OpenGridToolStripMenuItem.Text = "Open Grid" ' 'MainForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(748, 400) Me.Controls.Add(Me.MenuStrip1) Me.IsMdiContainer = True Me.MainMenuStrip = Me.MenuStrip1 Me.Name = "MainForm" Me.Text = "Delete DataGridView Rows Error Sample" Me.MenuStrip1.ResumeLayout(False) Me.ResumeLayout(False) Me.PerformLayout() End Sub Friend WithEvents MenuStrip1 As System.Windows.Forms.MenuStrip Friend WithEvents OpenGridToolStripMenuItem As System.Windows.Forms.ToolStripMenuItemEnd Class |
Here's the code for MainForm.vb:
Public Class MainForm Private Sub OpenGridToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenGridToolStripMenuItem.Click Dim f As Form = New ViewForm()f.MdiParent = Mef.Show() End SubEnd Class |
Here's the code for ViewForm.designer.vb:
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ Partial Public Class ViewForm Inherits System.Windows.Forms.Form 'Form overrides dispose to clean up the component list.<System.Diagnostics.DebuggerNonUserCode()> _ Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing AndAlso components IsNot Nothing Thencomponents.Dispose() 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.<System.Diagnostics.DebuggerStepThrough()> _ Private Sub InitializeComponent() Me.grdTests = New System.Windows.Forms.DataGridView Me.DataGridViewButtonColumn1 = New System.Windows.Forms.DataGridViewButtonColumn Me.DataGridViewButtonColumn2 = New System.Windows.Forms.DataGridViewButtonColumn Me.DataGridViewButtonColumn3 = New System.Windows.Forms.DataGridViewButtonColumn Me.DataGridViewTextBoxColumn1 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn2 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn3 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn4 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn5 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn6 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn7 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn8 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn9 = New System.Windows.Forms.DataGridViewTextBoxColumn Me.DataGridViewTextBoxColumn10 = New System.Windows.Forms.DataGridViewTextBoxColumn CType(Me.grdTests, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'grdTests ' Me.grdTests.AllowUserToAddRows = False Me.grdTests.AllowUserToDeleteRows = False Me.grdTests.AllowUserToOrderColumns = True Me.grdTests.Columns.Add(Me.DataGridViewButtonColumn1) Me.grdTests.Columns.Add(Me.DataGridViewButtonColumn2) Me.grdTests.Columns.Add(Me.DataGridViewButtonColumn3) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn1) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn2) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn3) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn4) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn5) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn6) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn7) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn8) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn9) Me.grdTests.Columns.Add(Me.DataGridViewTextBoxColumn10) Me.grdTests.Dock = System.Windows.Forms.DockStyle.Fill Me.grdTests.Location = New System.Drawing.Point(0, 0) Me.grdTests.Name = "grdTests" Me.grdTests.ReadOnly = True Me.grdTests.Size = New System.Drawing.Size(609, 448) Me.grdTests.TabIndex = 0 ' 'DataGridViewButtonColumn1 ' Me.DataGridViewButtonColumn1.HeaderText = "" Me.DataGridViewButtonColumn1.Name = "Edit" Me.DataGridViewButtonColumn1.ReadOnly = True Me.DataGridViewButtonColumn1.Width = 60 ' 'DataGridViewButtonColumn2 ' Me.DataGridViewButtonColumn2.HeaderText = "" Me.DataGridViewButtonColumn2.Name = "View" Me.DataGridViewButtonColumn2.ReadOnly = True Me.DataGridViewButtonColumn2.Width = 60 ' 'DataGridViewButtonColumn3 ' Me.DataGridViewButtonColumn3.HeaderText = "" Me.DataGridViewButtonColumn3.Name = "Delete" Me.DataGridViewButtonColumn3.ReadOnly = True Me.DataGridViewButtonColumn3.Width = 60 ' 'DataGridViewTextBoxColumn1 ' Me.DataGridViewTextBoxColumn1.HeaderText = "Name" Me.DataGridViewTextBoxColumn1.Name = "TestName" Me.DataGridViewTextBoxColumn1.ReadOnly = True ' 'DataGridViewTextBoxColumn2 ' Me.DataGridViewTextBoxColumn2.HeaderText = "Type" Me.DataGridViewTextBoxColumn2.Name = "TestType" Me.DataGridViewTextBoxColumn2.ReadOnly = True ' 'DataGridViewTextBoxColumn3 ' Me.DataGridViewTextBoxColumn3.HeaderText = "Date" Me.DataGridViewTextBoxColumn3.Name = "DateTested" Me.DataGridViewTextBoxColumn3.ReadOnly = True ' 'DataGridViewTextBoxColumn4 ' Me.DataGridViewTextBoxColumn4.HeaderText = "Sample" Me.DataGridViewTextBoxColumn4.Name = "SampleName" Me.DataGridViewTextBoxColumn4.ReadOnly = True ' 'DataGridViewTextBoxColumn5 ' Me.DataGridViewTextBoxColumn5.HeaderText = "Log" Me.DataGridViewTextBoxColumn5.Name = "LogNumber" Me.DataGridViewTextBoxColumn5.ReadOnly = True ' 'DataGridViewTextBoxColumn6 ' Me.DataGridViewTextBoxColumn6.HeaderText = "Material" Me.DataGridViewTextBoxColumn6.Name = "MaterialType" Me.DataGridViewTextBoxColumn6.ReadOnly = True ' 'DataGridViewTextBoxColumn7 ' Me.DataGridViewTextBoxColumn7.HeaderText = "Class" Me.DataGridViewTextBoxColumn7.Name = "Classification" Me.DataGridViewTextBoxColumn7.ReadOnly = True ' 'DataGridViewTextBoxColumn8 ' Me.DataGridViewTextBoxColumn8.HeaderText = "Thick" Me.DataGridViewTextBoxColumn8.Name = "Thickness" Me.DataGridViewTextBoxColumn8.ReadOnly = True ' 'DataGridViewTextBoxColumn9 ' Me.DataGridViewTextBoxColumn9.HeaderText = "Height" Me.DataGridViewTextBoxColumn9.Name = "Height" Me.DataGridViewTextBoxColumn9.ReadOnly = True ' 'DataGridViewTextBoxColumn10 ' Me.DataGridViewTextBoxColumn10.HeaderText = "Length" Me.DataGridViewTextBoxColumn10.Name = "Length" Me.DataGridViewTextBoxColumn10.ReadOnly = True ' 'ViewForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(609, 448) Me.Controls.Add(Me.grdTests) Me.Name = "ViewForm" Me.Text = "Some Data" CType(Me.grdTests, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) End Sub Friend WithEvents grdTests As System.Windows.Forms.DataGridView Friend WithEvents DataGridViewButtonColumn1 As System.Windows.Forms.DataGridViewButtonColumn Friend WithEvents DataGridViewButtonColumn2 As System.Windows.Forms.DataGridViewButtonColumn Friend WithEvents DataGridViewButtonColumn3 As System.Windows.Forms.DataGridViewButtonColumn Friend WithEvents DataGridViewTextBoxColumn1 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn2 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn3 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn4 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn5 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn6 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn7 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn8 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn9 As System.Windows.Forms.DataGridViewTextBoxColumn Friend WithEvents DataGridViewTextBoxColumn10 As System.Windows.Forms.DataGridViewTextBoxColumnEnd Class |
Here's the code for ViewForm.vb:
Imports System.Windows.Forms Imports System.CollectionsPublic Class ViewForm# Region "Member Variables" Private _rows As Hashtable# End Region ' Member Variables# Region "Constructors" Public Sub New()InitializeComponent() End Sub# End Region ' Constructors# Region "Initialization" Private Sub loadHash()_rows = New Hashtable() For row As Integer = 1 To 10 Dim colValues(10) As String For col As Integer = 1 To colValues.GetUpperBound(0)colValues(col) = "Row " + row.ToString() + ", Column " + col.ToString() Next_rows.Add(row, colValues) Next End Sub# End Region ' Initialization# Region "Grid Loading" Private Sub loadGrid() Me.grdTests.Rows.Clear() For row As Integer = 1 To 10 Me.grdTests.Rows.Add(createGridRow(row)) Next End Sub Private Function createGridRow(ByVal rowNumber As Integer) As DataGridViewRow Dim row As DataGridViewRow = New DataGridViewRow()row.Tag = rowNumber row.Cells.Add(createButtonCell( "Edit", "Click me to edit this row"))row.Cells.Add(createButtonCell( "View", "Click me to view this row"))row.Cells.Add(createButtonCell( "Delete", "Click me to delete this row")) Dim cellText() As String = DirectCast(_rows(rowNumber), String()) For col As Integer = 1 To cellText.GetUpperBound(0)row.Cells.Add(createTextCell(cellText(col))) Next Return row End Function Private Function createTextCell(ByVal cellText As String) As DataGridViewTextBoxCell Dim tc As DataGridViewTextBoxCell = New DataGridViewTextBoxCell()tc.Value = cellText Return tc End Function Private Function createButtonCell(ByVal cellText As String, ByVal tip As String) As DataGridViewButtonCell Dim tb As DataGridViewButtonCell = New DataGridViewButtonCelltb.Value = cellText tb.ToolTipText = tip Return tb End Function# End Region ' Grid Loading# Region "Grid Event Handling" Private Sub onButtonCellClick(ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Select Case Me.grdTests.CurrentCell.Value.ToString() Case "Edit"MsgBox( "You selected to Edit row " + (e.RowIndex + 1).ToString()) Case "View"viewRow(e.RowIndex) Case "Delete"deleteRow(e.RowIndex) End Select End Sub Private Sub deleteRow(ByVal row As Integer) If _rows.ContainsKey(Me.grdTests.Rows(row).Tag) Then_rows.Remove( Me.grdTests.Rows(row).Tag) Me.grdTests.Rows.RemoveAt(row) End If End Sub Private Sub viewRow(ByVal row As Integer) Dim cellText As String = grdTests.Rows(row).Cells(3).Value.ToStringMsgBox( "Text in column 4 of row " + (row + 1).ToString() + " is " + cellText) End Sub Private Sub grdTests_CellClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdTests.CellClickonButtonCellClick(e) End Sub# End Region ' Grid Event Handling# Region "Form Event Handling" Private Sub TestListViewForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LoadloadHash() loadGrid() End Sub# End Region ' Form Event HandlingEnd Class |

Problem removing last two rows of DataGridView
Davidsfg1
Do you know if this fix is in the July CTP
Thanks,
Brian
Barry Gervin
thanks,
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
Johan A
As you requested, I filed a bug report for this issue. I included a ZIP of a sample that demonstrates this issue.
-Brian
Bene_Ries
-mark
Program Manager
Microsoft
This post is provided "as-is"
whidbey_boy
thanks for reporting this!
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"