Solved

Datagridview - updating problems part II

Posted on 2006-11-06
4
221 Views
Last Modified: 2010-04-23
Sancler, I hope you're out there somewhere....

I have a datagrid that's bound directly to a dataset. I also have a button on my form with following eventhandler:
 
Private Sub btnUpdate_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
        DataGridView1.BindingContext(ds.Tables(0)).EndCurrentEdit()
        Try
            For Each row As DataRow In ds.Tables(0).Rows
                If row.RowState = DataRowState.Modified Then
                    db.CropMasterUpdate(IIf(IsDBNull(row.Item(0)), "", row.Item(0)), _
                                            IIf(IsDBNull(row.Item(1)), "", row.Item(1)), _
                                            IIf(IsDBNull(row.Item(2)), "", row.Item(2)), _
                                            IIf(IsDBNull(row.Item(3)), "", row.Item(3)), _
                                            IIf(IsDBNull(row.Item(4)), "", row.Item(4)), _
                                            IIf(IsDBNull(row.Item(5)), 0, row.Item(5)), _
                                            IIf(IsDBNull(row.Item(6)), 0, row.Item(6)), _
                                            IIf(IsDBNull(row.Item(7)), 0, row.Item(7)), _
                                            IIf(IsDBNull(row.Item(8)), 0, row.Item(8)))

                End If
                BindGrid()
            Next
         Catch ex As Exception
        End Try
    End Sub

I also have textboxes and a populate item which goes through selected rows and fills in the cells:

Private Sub btnPopulate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPopulate.Click
        Me.Cursor = Cursors.WaitCursor
        If Me.DataGridView1.SelectedRows.Count > 0 Then
            For Each row As DataGridViewRow In Me.DataGridView1.SelectedRows
                row.Cells(5).Value = IIf(Me.txtTop.Text = "", 0, Me.txtTop.Text))
                row.Cells(6).Value = IIf(Me.txtBottom.Text = "", 0, Me.txtBottom.Text)
                row.Cells(7).Value = IIf(Me.txtLeft.Text = "", 0, Me.txtLeft.Text)
                row.Cells(8).Value = IIf(Me.txtRight.Text = "", 0, Me.txtRight.Text)

                ds.AcceptChanges()
            Next
        End If
        Me.Cursor = Cursors.Default
    End Sub


However, when I make a change on a single row and hit update, it doesn't pick up the current row as having been editted (and therefore doesn't update the database).  The row.RowState shows "unchanged".  Sometimes when I make a bulk update to the datagridview, it doesn't even pick up those changes for reasons I do not know.
Also, when I make a change directly in the Datagridview, it sometimes picks up the change and saves... sometimes doesn't.  Is there a sure-fire way to pick up all the changes to the datagridview so that I can save to the database?  

This is rather urgent.  All replies are appreciated.
Regards,
0
Comment
Question by:adwooley2
  • 2
4 Comments
 
LVL 34

Accepted Solution

by:
Sancler earned 250 total points
ID: 17880380
I'm not sure I've followed it all, but my current guess is that this line in your btnPopulate_Click sub is your problem -

                ds.AcceptChanges()

What that does is reset all .RowState flags to .Unchanged.  If you want to call it at all, you should do so AFTER and not before you have saved any changes from the dataset to the database.

Roger
0
 
LVL 13

Assisted Solution

by:newyuppie
newyuppie earned 250 total points
ID: 17881476
some thoughts:
1) first, roger has a point, when you call the AcceptChanges you are reseting the row states so nothing will be persisted to the database. try deleting that line.
2) i would remove the Try structure, you are already checking for nulls so you wont have any errors in that department. if you feel there could be some other type of error thrown, try catching the specific error to avoid performance hit. you could catch a NullReference error and remove the IIF part, or keep the IIF part and remove the error catching.
3) i dont really see the point in looping through each row and checking its modified flag, and then performing updates on row to row basis. i see that more as a performance overhead, you might just as well call the dataadapter update method without checking each row, and it will persist those rows that are Modified automatically, removing this extra step.
4) finally, i think you need to change the current cell in which you have made changes order to pass the row from unchanged to modified, thus updating the database. what happens if you tab or click on a different cell after you made your changes, does it update correctly then?
0
 
LVL 13

Expert Comment

by:newyuppie
ID: 17881500
5) you could set the column's default value in the datatable to "0" instead of checking for nulls using the IIF. this way you will get the 0 automatically. this for integer or numerical columns. on the other hand set the string column's default value to string.empty.
0
 

Author Comment

by:adwooley2
ID: 17886128
Appreciate all the attention :)   And thanks for being there Sancler!
I had a funny feeling about that ds.AcceptChanges().  Removed that.
For newyuppie,
1) Understood
2) I had more to the Try structure, but for now, will remove
3) I am passing updates to a stored procedure. Don't know if a da can take updates and run it through an sp.
Now my update code looks like below (null checking will be changed per newyuppie's suggestion later).  Once I removed the Try structure, it revealed an error where the ds.Tables(0).GetChanges returned a NullReferenceException.   In other words, if I pressed the Update button when there were no changes, it caused a NullReferenceException.  So, by checking "If Not tbl Is Nothing" then it seems to operate correctly.  (Don't know if that makes sense).

    Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
        DataGridView1.BindingContext(ds.Tables(0)).EndCurrentEdit()
        Dim tbl As DataTable
        tbl = ds.Tables(0).GetChanges
        If Not tbl Is Nothing Then
            For Each row As DataRow In tbl.Rows
                db.CropMasterUpdate(IIf(IsDBNull(row.Item(0)), "", row.Item(0)), _
                                            IIf(IsDBNull(row.Item(1)), "", row.Item(1)), _
                                            IIf(IsDBNull(row.Item(2)), "", row.Item(2)), _
                                            IIf(IsDBNull(row.Item(3)), "", row.Item(3)), _
                                            IIf(IsDBNull(row.Item(4)), "", row.Item(4)), _
                                            IIf(IsDBNull(row.Item(5)), 0, row.Item(5)), _
                                            IIf(IsDBNull(row.Item(6)), 0, row.Item(6)), _
                                            IIf(IsDBNull(row.Item(7)), 0, row.Item(7)), _
                                            IIf(IsDBNull(row.Item(8)), 0, row.Item(8)))

            Next
        End If

        BindGrid()
    End Sub

Again, I appreciate your help.  Let's hope there isn't a "part III" to this saga.
Regards,
ADWooley
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question