none
System error when trying to delete a DataGridView row RRS feed

  • Question

  • Hi,
    I am trying to use DataGridView control with a BusinessObject and as part of getting familiar with relevant components I downloaded IBindingList Interface and IEditableObject Interface samples from the following links:

    http://msdn2.microsoft.com/en-us/library/system.componentmodel.ibindinglist(VS.80).aspx
    http://msdn2.microsoft.com/en-us/library/system.componentmodel.ieditableobject(VS.80).aspx) and

    I am able to set up DataGridView and customise the code for my situation but I also have some basic problems.

    When I try to delete Row 1 (for instance) by selecting the grid row and press delete I get the following error (even by using the code exactly as downloaded):

    The following exception occurred in the DataGridView:

    System.IndexOutOfrangeException: Index 1 does not have a value.
        at System.Windows.Forms.Currencymanager.getItem(Int32 index)
        at System.Windows.Forms.dataGridViewdataConnection.getError(Int32 rowIndex)

    To replace this default dialog please handle the DataError event.


    It appears that DataGridView and CustomersList object get out of sync. I thought that by implementing both interfaces it would allow DataGridView to synchronise with the underlying data without any other intervention! Also, if I added a new item to the CustomersList how would I go about updating DataGridView with the change or would that happen automatically?

    Also, to programmatically insert/duplicate some rows how would I go about it?
    Should I do it in dataGridView and let it propagate to the Business Object or vice verse?

    And finally, I would like to filter rows based on one column (called Originator in this instance) but I just can't get it working. I'm using the following (sample) code:

            ' Set data source for NotesBindingSource.
            NotesBindingSource.DataSource = Me.Notes

            ' Filter the items to show contacts who are owners.
            NotesBindingSource.Filter = "Originator = 'Text 1'"

            ' Set the data source for dataGridView1 to NotesBindingSource.
            DataGridView1.DataSource = NotesBindingSource

    I would really appreciate some help on this as I'm running desperately behind schedule.

    Thanks,
         Michael


    Thursday, March 6, 2008 12:22 AM

Answers

  • Here's a more complete example - I found out that the columns do not show up in the right order, but the code shows you how to reorder them. To try this code,just drop a datagriview on the form and a btnShowList, and then replace all the code in the editor with this:

     

    Public Class Form1

    Private Class Customer

    Private _FirstName As String = String.Empty

    Private _LastName As String = String.Empty

    Private _MiddleName As String = String.Empty

     

    Public Property FirstName() As String

    Get

    Return _FirstName

    End Get

    Set(ByVal value As String)

    _FirstName = value

    End Set

    End Property

     

     

    Public Property LastName() As String

    Get

    Return _LastName

    End Get

    Set(ByVal value As String)

    _LastName = value

    End Set

    End Property

     

     

    Public Property MiddleName() As String

    Get

    Return _MiddleName

    End Get

    Set(ByVal value As String)

    _MiddleName = value

    End Set

    End Property

    End Class

     

    Private Customers As New List(Of Customer)

     

     

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

    Dim bs As New BindingSource

    bs.DataSource = Customers

    DataGridView1.DataSource = bs

    Dim columnIndex As Integer = 0

    'Set the column order so that "FirstName" comes first, then LastName

    For Each col As String In New String() {"FirstName", "MiddleName", "LastName"}

    DataGridView1.Columns(col).DisplayIndex = columnIndex

    columnIndex += 1

    Next

    AddHandler btnShowList.Click, AddressOf btnShowList_Click

    End Sub

     

     

    Private Sub btnShowList_Click(ByVal sender As Object, ByVal e As EventArgs)

    Dim str As String = String.Empty

    For Each C As Customer In Customers

    str &= C.FirstName & " " & C.MiddleName & " " & C.LastName + vbCrLf

    Next

    MessageBox.Show(str)

    End Sub

    End Class

     

     

     

    Thursday, March 13, 2008 7:11 AM

All replies

  •  

    Bizzare - i've got this too,

     

    was about to try:

     

    DataGridViewRow row = grid.Rows[e.RowIndex];

    grid.Rows.Remove(row);

     

    but Studio hung... give that a go after deleting the CustomerList object / any other data structure involved.

    Thursday, March 6, 2008 5:43 PM
  • That is exactly what I'm doing, sorry I didn't supply the code to begin with.
    I tried various combinations and the following code gave me the least number of errors:

        Private Sub DeleteCustomersToolStripButton_Click(ByVal sender As System.Object, _
                                     ByVal e As System.EventArgs) Handles DeleteCustomersToolStripButton.Click
            For Each Item As DataGridViewRow In Me.DataGridView1.SelectedRows
                Me.Customers.RemoveAt(Item.Index)
                Me.DataGridView1.Rows.Remove(Item)
            Next
        End Sub




    Thursday, March 6, 2008 10:34 PM
  •  

    I got mine to work using BindingSource;

     

    BindingSource bindingSource = new BindingSource();

    bindingSource .DataSource = list;

     

    dataGridView1.DataSource = bindingSource;

     

     

    Friday, March 7, 2008 10:06 AM
  • I think that I'm effectively doing the same thing, as per code below, and I still get errors.
    I guess there must be something else that is set differently in my environment.

    /Michael


            ' Note that Me.Notes is an IList collection of IEditableObject objects
            NotesBindingSource.DataSource = Me.Notes                     
            DataGridView1.DataSource = NotesBindingSource
    Sunday, March 9, 2008 4:50 AM
  • I'm not understanding why you would need to manually implement the IBindingList or IEditableObject. I would think that you simply need to do the following (assuming you are using .Net 2.0) - I say this because I'm guessing that all the Interfaces and methods need for databinding are already implemented in BindingSource and Generic Cllection.

     

    Private Class Customer

    public  FirstName as String

    public LastName as String

    End Class

     

    And then:

     

     

    Dim Customers as New List(of Customer) simple generic collection, easy to  use.

    'Build your list

    Dim oCust  as New Customer

    Customers.Add(oCust) 'etc, continue building list.

    Dim bs as New BindingSource

    bs.DataSource = Customers

    datagridView1.DataSource = bs

     

    I haven't tried any of this, but I have tried similar code - binding a datable to a datagridview. And no, I didn't have to manually manipualte the underlying datatable. When I used the keyboard to a delete a row, for example, the datatable was affected automatically.

     

     

     

     

     

     

     

     

    Wednesday, March 12, 2008 6:46 AM
  • Thanks for that jal2.

    As you can see I'm not very comfortable with binding data to Business Objects and by reading various articles got the idea that I had to implement IBindingList or IEditableObject but what you're saying also makes sense.

    Because of problems described in this post and also some other issues, I had to change the approach to implementing that functionality and I'm currently focusing on finalising some other functions else but shortly I will need to implement some other functions using the above approach and I'll try your suggestion.

    Hopefully I'll be doing that in the next few days and I'll let you know how I go but for now thanks a lot for your input and I hope it works.

    /Michael
    Thursday, March 13, 2008 12:03 AM
  • Here's a more complete example - I found out that the columns do not show up in the right order, but the code shows you how to reorder them. To try this code,just drop a datagriview on the form and a btnShowList, and then replace all the code in the editor with this:

     

    Public Class Form1

    Private Class Customer

    Private _FirstName As String = String.Empty

    Private _LastName As String = String.Empty

    Private _MiddleName As String = String.Empty

     

    Public Property FirstName() As String

    Get

    Return _FirstName

    End Get

    Set(ByVal value As String)

    _FirstName = value

    End Set

    End Property

     

     

    Public Property LastName() As String

    Get

    Return _LastName

    End Get

    Set(ByVal value As String)

    _LastName = value

    End Set

    End Property

     

     

    Public Property MiddleName() As String

    Get

    Return _MiddleName

    End Get

    Set(ByVal value As String)

    _MiddleName = value

    End Set

    End Property

    End Class

     

    Private Customers As New List(Of Customer)

     

     

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

    Dim bs As New BindingSource

    bs.DataSource = Customers

    DataGridView1.DataSource = bs

    Dim columnIndex As Integer = 0

    'Set the column order so that "FirstName" comes first, then LastName

    For Each col As String In New String() {"FirstName", "MiddleName", "LastName"}

    DataGridView1.Columns(col).DisplayIndex = columnIndex

    columnIndex += 1

    Next

    AddHandler btnShowList.Click, AddressOf btnShowList_Click

    End Sub

     

     

    Private Sub btnShowList_Click(ByVal sender As Object, ByVal e As EventArgs)

    Dim str As String = String.Empty

    For Each C As Customer In Customers

    str &= C.FirstName & " " & C.MiddleName & " " & C.LastName + vbCrLf

    Next

    MessageBox.Show(str)

    End Sub

    End Class

     

     

     

    Thursday, March 13, 2008 7:11 AM
  • I also just realized that BindingSource has some helpful events which you can handle, for better control of the situation, such as the ListChanged event.

     

    Thursday, March 13, 2008 7:19 AM
  • Thanks jal2, I'll try that out as soon as I get a chance.

    /Michael

    Thursday, March 13, 2008 8:00 AM
  • Hi jal2,
    Sorry for not responding sooner, I kept being signed out when I tried to post a response.

    But as far as your suggestion goes, it worked as you suggested so thanks a lot.
    I'm not sure now why I came to the conclusion that I had to implement IBindingList!!!

    In any case all is Ok now so once again, thanks a lot.

    /Michael

    Wednesday, March 26, 2008 1:37 AM
  • Hi jal2,
    Sorry for not responding sooner, I kept being signed out when I tried to post a response.

    But as far as your suggestion goes, it worked as you suggested so thanks a lot.
    I'm not sure now why I came to the conclusion that I had to implement IBindingList!!!

    In any case all is Ok now so once again, thanks a lot.

    /Michael

    Wednesday, March 26, 2008 1:37 AM