This is a migrated thread and some comments may be shown as answers.

Grid tries to sort when custom sorting is specified on a column

9 Answers 471 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Chris Smith
Top achievements
Rank 1
Chris Smith asked on 01 Aug 2008, 01:49 PM
We are currently using a single grid to display data for multiple "tabs" (in reality a restyled listbox where we bind a new data source to the grid when the selected item changes).

Different tabs can have different columns displayed, so we regenerate the collection of GridViewDataColumn objects whenever tab is switched.  We always set IsCustomSortingEnabled to true on these objects.  We then hook the SortingRequested event and refetch our data whenever a column header is clicked and the collection of sorting criteria changes.  This works fine when a column header is clicked, but breaks when we switch to a tab that was previously sorted.

When we switch to a previously sorted tab, we regenerate the GridViewDataColumn collection (setting IsCustomSortingEnabled to true as ever), clear SortDescriptions on the grid and repopulate it with the correct SortDescription objects.

The problem is that setting these SortDescription's appears to trigger the RadGridView's native sorting mechanism, at which point it complains that our domain objects don't implement IComparable.  I've attached the stack trace at the end of this post.

So it looks as if somewhere in the grid code IsCustomSortingEnabled is not being checked.

All help gratefully received

Regards

Chris

-----------------

at System.Collections.Comparer.Compare(Object a, Object b)
at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
at Telerik.Windows.Data.Grouping.NullValuesComparer`1.Compare(Object x, Object y)
at Telerik.Windows.Data.Grouping.SortDescriptionComparer`1.CompareWithIndexes(Int32 xIndex, TElement xElement, Int32 yIndex, TElement yElement)
at Telerik.Windows.Data.Grouping.SortDescriptionsComparer`1.CompareWithIndexes(Int32 xIndex, TElement xElement, Int32 yIndex, TElement yElement)
at Telerik.Windows.Data.Grouping.DataSourceIndexComparer`1.Compare(Int32 x, Int32 y)
at System.Linq.EnumerableSorter`2.CompareKeys(Int32 index1, Int32 index2)
at System.Linq.EnumerableSorter`1.QuickSort(Int32[] map, Int32 left, Int32 right)
at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Telerik.Windows.Data.Grouping.DataRecordList`1.get_UnfilteredIndexes()
at Telerik.Windows.Data.Grouping.DataRecordList`1.get_DataSourceIndexes()
at Telerik.Windows.Data.Grouping.DataRecordList`1.get_Count()
at Telerik.Windows.Data.VirtualizingRecordCollection.get_Count()
at Telerik.Windows.Data.VirtualizingRecordCollection.System.Collections.ICollection.get_Count()
at MS.Internal.Data.IndexedEnumerable.GetNativeIsEmpty(Boolean& isEmpty)
at MS.Internal.Data.IndexedEnumerable.get_IsEmpty()
at System.Windows.Data.CollectionView.get_IsEmpty()
at System.Windows.Data.CollectionView.RefreshOverride()
at System.Windows.Data.CollectionView.RefreshInternal()
at System.Windows.Data.CollectionView.RefreshOrDefer()
at System.Windows.Data.CollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at Telerik.Windows.Data.VirtualizingRecordCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at Telerik.Windows.Data.VirtualizingRecordCollection.OnCollectionReset()
at Telerik.Windows.Data.VirtualizingRecordCollection.Reset()
at Telerik.Windows.Data.VirtualizingRecordCollection.set_RealRecords(IList`1 value)
at Telerik.Windows.Data.RecordManager.RecalculateGroups()
at Telerik.Windows.Data.RecordManager.SortDescriptions_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at Telerik.Windows.Data.RadObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at Telerik.Windows.Data.RadObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedAction action, Object item, Int32 index)
at Telerik.Windows.Data.RadObservableCollection`1.InsertItem(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at Epro.ClientControls.Entity.DataGrid.EntityGridSortHandler.SetSortedColumnHeaders(ICollection`1 sortDescriptions, IEnumerable`1 propertiesToDisplay) in C:\Epro4Trunk\Epro.ClientControls\Entity\DataGrid\EntityGridSortHandler.cs:line 63

9 Answers, 1 is accepted

Sort by
0
Atanas
Telerik team
answered on 04 Aug 2008, 02:29 PM
Hello Chris Smith,

As I understand your application crashes after rebinding previously sorted RadGridView control to a different datasource.

Our data engine is implemented with the thought that rebinding is reasonable after data update or other similar operation, to one and the same datasource. Changing the datasource at runtime requires to clear the Columns collection and SortDescriptions at least.

I hope our DataBinding example is helpfull for the issue you have, take a look at the ResetRadGridView method.  Before changing the RadGridView datasource it is necessary to explicitly clear all SortDescriptions, GroupDesctiptions, FilterDescriptions and Columns.

If all this does not solve your problems, please send us more details, possibly some step-by-step instructions, on reproducing the issue.

Sincerely yours,
Atanas
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Chris Smith
Top achievements
Rank 1
answered on 04 Aug 2008, 03:19 PM
Hi Atanas

I have tried explicitly clearing everything before we change what is attached to the ItemsSource property of the RadGridView, but we still have the same problem.

The problem is that we have custom sorting implemented on the server.  Hence if a user clicks on a column header to change sorting, we refetch from the server.

This means that when we change the data source attached to the grid, we need to set the sorting on the columns to reflect the sorting on that data source.  To do this, we set IsCustomSortingEnabled to true on all columns and then add a new SortDescription to the (previously cleared) collection of SortDescription objects associated with the grid for each column that should appear sorted.

The problem is that adding to RadGridView.SortDescriptions triggers normal sorting (IsCustomSortingEnabled on the column is being ignored)m at which point the grid throws an error saying that the domain objects for the column don't implement IComparable.

Can you confirm that adding to RadGridView.SortDescriptions always triggers sorting, irrespective of the value of IsCustomSortingEnabled?

Regards

Chris
0
Atanas
Telerik team
answered on 05 Aug 2008, 11:24 AM
Hi Chris Smith,

Yes, I assure you that adding SortDescription to RadGridView.SortDescriptions always triggers built-in sorting, despite of IsCustomSortingEnabled property value.

Our idea of custom sorting implementation totally exclude adding SortDescripton in RadGridView.SortDescriptions collection. Each column from RadGridView.Columns has a property SortingState of enum type which is used to show sort direction. I recommend you to take a look at our CustomSorting example.

After custom sorting all you need to do is to display the respective sorting direction in the column header and here comes the SortingState property, for example:

RadGridView.Columns["City"].SortingState = SortingState.Ascending;


Kind regards,
Atanas
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Chris Smith
Top achievements
Rank 1
answered on 05 Aug 2008, 02:05 PM
Hi Atanas

Thanks very much for your quick reply.

We have stopped using SortDescriptions completely and are now just setting the SortingState on relevant columns.

This stops the exception being thrown (due to our domain objects not implementing IComparable), but we have a couple of other (relatively minor) problems:

- When we set SortingState for a given column to ascending, the triangle in the column header is pointing down, and when we set descending, the triangle is pointing up

- This triangle doesn't appear when we set the SortingState for a given column.  We have to regenerate the collection of columns for the grid and set their SortingState properties for the triangles to appear.

Our app is now working, but it's a bit uncomfortable to have to completely regenerate the columns every time a sort direction is changed on a single column.  Do you know of a better way of doing this?

Many thanks

Chris
0
Atanas
Telerik team
answered on 05 Aug 2008, 03:38 PM
Hi Chris Smith,

The SortingState property has to be set after RadGridView is shown, so the right place to do it is Loaded event of RadGridView.

private

void RadGridView_Loaded(object sender, RoutedEventArgs e)
{
    
 this.radGridView1.Columns[0].SortingState = SortingState.Ascending;
}


If this does not solve your problem, we will seek other ways to fix the issue.

Regards,
Atanas
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Chris Smith
Top achievements
Rank 1
answered on 05 Aug 2008, 03:57 PM
Hi Atanas

I don't think this solves the problem?  We need to be able to set SortingState on a column and see the triangle appear.  The grid is loaded already and the user clicks a column header, at which point we catch the SortingRequested event and set the SortingState of the column that was clicked on.

Unfortunately, this doesn't give any visual feedback unless we do something heavy-handed like regenerating the column collection.

Can you tell me what the setter for SortingState is doing?

Regards

Chris
0
Accepted
Atanas
Telerik team
answered on 06 Aug 2008, 02:25 PM
Hi Chris Smith,

As I understand you use a single RadGridView control and a TabControl with several TabItems. If I am right, the idea of your project is to rebind the RadGridVew control to a different ItemsSource each time the SelectedItem(of TabControl) is changed and your wish is to keep sorted directions of all columns without recreating them.

So, I made for you a simple project reproducing this scenario. Take a look at SelectionChanged event handler of my TabControl, it is important to reset the value of the previouslySortedColumn field. I suspect, you might have one in your code, and sorting by a column in TabX might cause clearing the sort direction on a column from TabY.

Greetings,
Atanas
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Chris Smith
Top achievements
Rank 1
answered on 06 Aug 2008, 04:24 PM
Hi Atanas

Thanks a lot for that - it solved our problem.  The problem was that we were setting SortingState on a column when we needed to set SortOrder on the SortingRequestedEventArgs being passed to the event handler.

We've modified your project to show the breaking behaviour - it was confusing that we could set SortingState on a column without any sort of exception and then not get the behaviour we expected.

The modified project has been uploaded as part of a feature request, because we can't upload to this forum (or at least we can't find a way to do it!).  The request number is 154518.

Thanks again

Regards

Chris
0
Atanas
Telerik team
answered on 07 Aug 2008, 02:26 PM
Hello Chris Smith,

If I understand correctly, the problem lies that setting a column's SortingState property in your SortingRequested event handler does not work, and you have to set the SortingRequestedEventArgs.SortOrder. Compared to requiring to set the column's SortingState property outside the event handler, it might be misleading to users of the code. We will take this into consideration and either reorganize the API to make it more intuitive or raise an exception when somebody sets the column property within that event handler.

Thanks for the suggestion. I have updated your Telerik points.

Best wishes,

Atanas
the Telerik team


Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Tags
GridView
Asked by
Chris Smith
Top achievements
Rank 1
Answers by
Atanas
Telerik team
Chris Smith
Top achievements
Rank 1
Share this question
or