I created a table, created a dataview, and sorted the dataview. I then populated the table with three rows of data and all was good. I then changed one of the fields (Hours) in one of the rows which SHOULD HAVE caused it to re-sort, but it did not re-sort. It seems to only affect the last row of the dataview. I tried removing and re-applying the sort condition with no luck. Any idea what is up here?

Function CreateStoreHours() As DataTable
    StoreHours.Columns.Add("Store", GetType(String))
    StoreHours.Columns.Add("Hours", GetType(Double))
    StoreHours.DefaultView.Sort = "Hours ASC"
    dgvStoresHours.DataSource = StoreHours
End Function

'Here I popluated the grid with three records. All were sorted correctly.

For v = 0 To StoreHours.DefaultView.Count - 1
    If row("Store") = StoreHours.DefaultView(v).Item("Store") Then
        Match = True
        StoreHours.DefaultView(v).Item("Hours") = StoreHours.DefaultView(v).Item("Hours") + row("Hours")
        'The Hours field gets adjusted properly, but it gets moved to the last record even 
        ' though it should be sorted as the second record of three. This is also where I tried
        ' the un-sort and re-sort with no luck.
        Exit For
    End If
Next

Recommended Answers

All 4 Replies

try:
DataGridView1.Columns("Hours").SortMode = DataGridViewColumnSortMode.Automatic

Update the underlying datatable directly. This will ensure that the changes are reflected in the dataview.

Something like this:

Public Class Form1

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

      Dim r As DataRow
      With dtSource
         .Columns.Add("store", GetType(String))
         .Columns.Add("hours", GetType(Double))
         r = .NewRow : r(0) = "s1" : r(1) = 3.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s1" : r(1) = 5.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s1" : r(1) = 51.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s1" : r(1) = 13.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s1" : r(1) = 33.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s2" : r(1) = 35.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s2" : r(1) = 54.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s2" : r(1) = 23.0# : .Rows.Add(r)
         r = .NewRow : r(0) = "s2" : r(1) = 31.0# : .Rows.Add(r)
         .DefaultView.Sort = "[hours] Asc"
      End With
      DataGridView1.DataSource = dtSource.DefaultView
   End Sub


   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      AddhoursToStore("s1", 50.0#)
   End Sub

   Sub AddhoursToStore(ByVal store As String, ByVal hrsToAdd As Double)
      For Each row As DataRow In dtSource.Select("[store] = '" & store & "'")
         row("hours") = CType(row("hours"), Double) + hrsToAdd
      Next
   End Sub
End Class

This was it, TnTinMN! Thanks for the help. Any idea why we can't just update through the defaultview? It seems like a real hole in the environment logic to have to update the table on it's own terms not using the defaultview portal...

This was it, TnTinMN! Thanks for the help. Any idea why we can't just update through the defaultview? It seems like a real hole in the environment logic to have to update the table on it's own terms not using the defaultview portal..

Sorry for taking so long to get back to. It slipped my mind.

A DatagridView is well just that, a view on the data that is supplied to it. In this case the source data is a DataView that is again a view of the DataView underlying data source that can be filtered and sorted to satisfy a particular requirement. It is not meant to be the data itself.

From the DataGridView you can find data source as that is a property of each datagridviewrow. These are stored as objects, so you need to know the original source type. In the case of a DataView, it is a DataRowView. The source of the DataRowView is a DataRow.

Confused yet?

Here is an example of the manipulations to get to the real data.

   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
      Dim r As DataRow
      Dim drv As DataRowView
      For Each row As DataGridViewRow In DataGridView1.Rows
         If row.DataBoundItem IsNot Nothing Then ' incase you have add new rows enabled
            ' 1st get the datagridviewrow's datasource
            drv = CType(row.DataBoundItem, DataRowView)
            ' now get the drv's datarow
            r = drv.Row
            ' now we are back at manipulating the orginal source
            If r("store").ToString = "s1" Then
               r("hours") = CDbl(r("hours")) + 50.0#
            End If
         End If
      Next
   End Sub

For your original problem it was easier to just go to the DataTable directly. However, say you wanted to perform an operation on a selected row and the data has been sorted. Then there would be no way to know the original row in the datatable that needs to be manipulated unless you go through this process to get it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.