Wednesday, December 11, 2013

Searching Sorted DataGrids

WPF version 4.0

I have a datagrid that shows some search results. The user can sort the results by clicking on the column headers. I also have a button that will search the grid and select the next row that contains a specific value. I started with code that looks like this. Note the code has been simplified to always return the first error. The real code to find the next error would start at the row after the current row and search to the end, then start at the beginning and search to the current row.

For i as integer = 0 to RowCount - 1
    If DirectCast(DataGrid.ItemsSource, DataView).Table.Rows(i)("HasErrors") > 0 Then
        DataGrid.SelectedIndex = i
        Exit For
    End if
Next

Which worked great until a user sorted the grid and then clicked the button. Then the code started highlighting random rows. I realized the table had not been resorted and the sequence of rows in the table no longer matched the sequence of rows in the datagrid. So, still thinking in asp.net mode, I decided to search the contents of the table instead. You can do this by using an Item container which returns a DataGridRow.

SearchResultsDataGrid.ItemContainerGenerator.ContainerFromIndex(i)

But this didn't work the way I wanted either because the datagrid is virtualized so there were only containers for the rows on the currently displayed page. If the next error was not on the current page it wouldn't be found.

I had to think like a WPF programmer. The answer is in the ItemsSource, not in the DataGrid. The secret is in noticing that the ItemsSource is a DataView, not a DataTable. The DataView is sorted when the DataGrid is sorted but the DataTable is not. I simply had to modify the code to search the DataView like this...

For i as integer = 0 to RowCount - 1
    If DirectCast(DataGrid.ItemsSource, DataView).Item(i)("HasErrors") > 0 Then
        DataGrid.SelectedIndex = i
        Exit For
    End if
Next

What threw me off is that a DataView contains a collection of items instead of a collection of rows. Who knows why? I don't!

No comments:

Post a Comment