I'm noticing a very odd behavior with column sorting in the grid. Upfront I will admit we are still on infragistics version 2010.1 (we had a release upcoming and couldn't wait for the multiple group by issue to be fixed)
I have a grid where for one column I have implemeneted a custom grid sorter (of type IComparer) and assigned that to the column's .SortComparer property.
While debugging another operation, I had need to disable all sorting. So in the grid's _BeforeSortChange event I set e.cancel = true;
When I did so, I noticed that clicking on a column header, while not performing a sort, still seemed to lock the UI thread briefly (for a very large dataset, after clicking the column header I was unable to focus any other component for a few seconds).
I put a breakpoint in Visual Studio in the _AfterSortChange event and never hit it.
However, I also put a breakpoint in my custom sort class's Compare() method and that one gets hit.
It *seems* as if, even though the cancel is set to true in the _BeforeSortChange method and no visual sort is performed, the sorting "logic" is still being performed by the grid.
For the record, I am not calling a RefreshSort() anywhere in the grid or in any other way kicking off a manual sort.
Is this behavior intended? If so is there some way I can work around it (besides dynamically adding / removing the sort class from the column).
Thanks,
Chris Rowland
Thanks for the reply Mike. In putting together a sample app for you to look at I discovered the behavior is a bit different than I described.
For the sake of the example, consider a scenario where my logic conditionally cancels the beforeSort event, such that one time it may be allowed to continue, other times not.
It appears that once a column using a GridSorter is sorted, even if every other sort event after that is canceled, the sort logic is still executed.
Attached is a very simple project containing a grid with 3 columns and 4 rows, and a simple sort comparer class that allows you to sort one column by the values in another.
The first column "CustNum" contains an instance of this sort comparer so as to sort by the second column "CustName".
At the class level I have an int counter set to zero.
In the BeforeSortChange event, if the counter is zero, I *don't* cancel the event and increment the counter, else I cancel. This mimics the behavior of the first sort being allowed, subsequent sorts canceled.
I have a Console.Writeline statement in my Sort Comparer's Compare method.
I expect to see the writeline values on first click of the column header. I expect to NOT see them on the 2nd and subsequent click, but I do.
This seems to me to prove that despite canceling the sort event, the sort logic is still being executed.
Hi,
I can't be sure, there might be some obscure reason for this, but at first glance, this looks like a bug to me. The grid's UIElement is getting dirtied and it's verifying the sorted order of the rows, but since the sort operation was canceled, I can't see any reason for the grid to be doing that. Looks like it's an oversight. It's not terribly harmful, which is probably why no one noticed it, but I can see how it might be detrimental to performance in some cases.
So I'm going to forward this thread over to Infragistics Developer Support and have them write this up for developer review.
Thanks for looking into this Mike.
In the meantime, is there any sort of workaround for this. Here's why it's especially detrimental for us.
Some time ago, our product management decided they wanted double-click, instead of single click, on a column header initiate a sort. To do this we jump through some hoops to cancel the sort event on the first click, but allow it on the second.
Because the cancel for the BeforeSort event isn't stopping the processing of the sort logic, when a user double clicks on a column in our app, it's essentially performing two sorts (but only displaying the results once).
When the dataset is small this isn't much of an issue. But as the number of rows grows, this becomes a very obvious performance hit.
Unless you have a suggestion, I'm probably going to suggest to management that we go back to single click sorting.
Hi Chris,
A column has to be sorted in order to be grouped, so I guess in most cases, it would not make sense for the HeaderClickAction to apply to the GroupByButton.
Are you allowing the users to do the grouping or are you doing it in code?
What you can probably do is use a flag that determines whether each change to sorting is allowed. Then you check that flag inside the BeforeSortChange event. Then any time you want to change the sorting in code, you set the flag first, then set the Sortindicator, then set the flag back.
Something like this:
private void ultraGrid1_DoubleClickHeader(object sender, DoubleClickHeaderEventArgs e) { switch (e.Header.Column.SortIndicator) { case SortIndicator.Ascending: this.SetSortIndicator(e.Header.Column, SortIndicator.Descending); break; case SortIndicator.None: case SortIndicator.Descending: this.SetSortIndicator(e.Header.Column, SortIndicator.Ascending); break; case SortIndicator.Disabled: break; } } private void SetSortIndicator(UltraGridColumn column, SortIndicator sortIndicator) { this.allowSortChange = true; try { column.SortIndicator = sortIndicator; } finally { this.allowSortChange = false; } } bool allowSortChange = false; private void ultraGrid1_BeforeSortChange(object sender, BeforeSortChangeEventArgs e) { if (false == this.allowSortChange) e.Cancel = true; }
If you need to group a column, you do the same thing with the flag, since grouping a column will fire BeforeSortChange. If you need the users to be able to group the columns, then it becomes a bit more complicated as you will have to put a check in BeforeSortChange to see if the groupings are changing and allow that.
Thanks Mike. That gets me *really close* to what I'm looking for. Single click on the column header is no longer triggering a BeforeSort event, and only fires once on double click.
The only unwanted behavior I'm seeing now is that this doesn't seem to apply to GroupByColumnHeaders when the grid is in ShowGroupBy mode and such a column exists. Single click on the group by column is still performing a sort.
I would think the HeaderClickAction would apply to all column headers but maybe that's not the case?
Thanks
How about turning off the grid's automatic sorting behavior and handling the toggling of the sort indicator yourself using the DoubleClickHeader event.
private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e) { UltraGridLayout layout = e.Layout; UltraGridOverride ov = layout.Override; // Turn off sorting. ov.HeaderClickAction = HeaderClickAction.Select; // Turn off column selection ov.SelectTypeCol = SelectType.None; } private void ultraGrid1_DoubleClickHeader(object sender, DoubleClickHeaderEventArgs e) { switch (e.Header.Column.SortIndicator) { case SortIndicator.Ascending: e.Header.Column.SortIndicator = SortIndicator.Descending; break; case SortIndicator.None: case SortIndicator.Descending: e.Header.Column.SortIndicator = SortIndicator.Ascending; break; case SortIndicator.Disabled: break; } }