I have group by with summary cells switched on in my UltraGrid, and it's grouping and calculating the summary values fine. When I click on the column header to sort by a column, it only sorts the actual rows within the group and not the group row as I expect like how it is with the nested tables. Is there a way to include sorting on the group by levels too?
Here is an example, a grid with group by rows.
Col1|Col2|Col3 (column headers)
1000|3000|3000 (group by row)
2000|2000 (row)
1000|1000 (row)
2000|2000|3000 (group by row)
1000|2000 (row)
When I click on column header Col2, I expect the result to look like this, sort the group by levels, and then row levels
Thanks.
Hi Michael,
The way Grouping works is that the grid must first sort by the grouped column (Col1). This ensures that matching values are adjacent. The grid then loops through the rows to find matching rows and group them.
It is possible to then sort the GroupByRows after that process has occurred, but there's no way for the grid to determine how you want the sorting to work automatically. The grid doesn't necessarily know that Col2 in your example has a summary and you want to sort the GroupByRows by that summary. So you can do this, buy you have to define the sort criteri for the GroupByRow using an IComparer via the GroupByComparer property of the column. This allows you to essentialy control the sorting of the GroupByRows for a particular grouped column (in this case Col1).
If you are setting up the grouping and sorting in code, and not allowing the user to change it, this is pretty easy. If you are letting the user sort and group by whatever they want, then it would be very difficult to implement this for every conceivable combination of grouping, sorting, and summaries.
I have attached a small sample project here that demonstrates how to do this in a very simple case similar to what you described here.
Sorting GroupByRows.zip
Thanks Mike for the sample. I was able to make it work the way I wanted it to work. One behavior I noticed, after adding the GroupByComparer, whenever it sorts, the vertical scrollbar scroll position would move. Is there a way to prevent that from happening? I don't want to change horizontal scroll position whenever I sort.
Are you sure you mean horizontal scrolling and not vertical? I can't think of any reason why sorting the grid would cause it to scroll horizontally.
The grid does try to keep the ActiveRow in view when you sort, so that would explain why it's scrolling vertically. It will do that with or without the GroupByComparer, but my guess is that the ActiveRow is a GroupByRow and since they weren't changing position before, you didn't see any scrolling. But you would have if a data row happened to be active.
To answer your question, there's no way to prevent the grid from trying to keep the ActiveRow in view. And there's really no way to keep the exact same scroll position, since the position no longer really exists after the row order has changed. But you could store the position and restore if after the sort.
Where it gets tricky is that the sorting is performed asynchronously. So you can store the position in the BeforeSortChange event, but you have to wait until the sorting is complete before you can restore it, and AfterSortChange will fire too soon. So what you can do is wait until the next time the grid paints. This might cause a flicker, since the grid will still be scrolling to the new position and then back, but there's no better way that I can think of.
int lastScrollPosition; private void ultraGrid1_BeforeSortChange(object sender, BeforeSortChangeEventArgs e) { this.lastScrollPosition = this.ultraGrid1.ActiveRowScrollRegion.ScrollPosition; this.ultraGrid1.Paint += UltraGrid1_Paint; } private void UltraGrid1_Paint(object sender, PaintEventArgs e) { this.ultraGrid1.Paint -= UltraGrid1_Paint; this.ultraGrid1.ActiveRowScrollRegion.ScrollPosition = this.lastScrollPosition; }
8272.Sorting GroupByRows.zip