Exception while trying to manually sort PagedCollectionView
Ok I think I'm doing something wrong here.
I am using a PagedCollectionView mapped to an ObservableCollection of a custom type. I want to be able to manually sort the underlying collection whenever the user tries to sort a DataGrid column.
I did the following:
obs = new ObservableCollection<Seats>(arrSeats);
view = new PagedCollectionView(obs);
INotifyCollectionChanged sortchangeNotifier = view.SortDescriptions as INotifyCollectionChanged;
sortchangeNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler(sortchangeNotifier_CollectionChanged);
grdData.ItemsSource = view;
void sortchangeNotifier_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// What to do here?
}
The event handler is being correctly invoked whenever the column header is clicked. However, whenever I try to modify the ObservableCollection, I get the fo开发者_如何学运维llowing exception:
Cannot change or check the contents or current position of the PagedCollectionView while Refresh is being deferred.
I want to be able to implement my own custom sorting algorithm. Any ideas?
Thanks!
EDIT
Well, this is particularly crazy, but when I wrap my code with a try/catch block in the event handler method, the changes are actually applied. Any ideas :) ?
The problem you really wanted to solve was having custom sorting of a PagedCollectionView --
"I am using a PagedCollectionView mapped to an ObservableCollection of a custom type. I want to be able to manually sort the underlying collection whenever the user tries to sort a DataGrid column."
Customizing/Extending the PagedCollectionView is the way to do this. When I had the need to do the same I created a dictionary of IComparer
public Dictionary<string, IComparer<object>> CustomSortFunctions
{
get
{
if (this.customSortFunctions == null)
{
this.customSortFunctions = new Dictionary<string, IComparer<object>>();
}
return this.customSortFunctions;
}
}
such that the key of each pair is intended to correspond to a DataGridColumn.SortMemberPath. For any column for which you desire custom sorting you add a suitable value pair.
To leverage this dictionary modify the SortList method of PagedCollectionView to check for a custom comparer to sort by (and then sort in the applicable direction). For instance:
if (this.CustomSortFunctions.ContainsKey(description.PropertyName))
{
source = source.OrderBy(a => a, this.CustomSortFunctions[description.PropertyName]);
}
As a user "sorts" with the data grid your desired sorting will occur.
Your starting point is the PagedCollectionView -- the source for which is included in the overall the source code for the Silveright Toolkit (in Toolkit/Systems.Windows.Data/PagedCollection).
Well a CollectionView and ObservableCollection go hand in hand for any notification changes. Hence any changes done to either of the two simultaneous to their change notification cause exceptions.
We would have to take a different approach for this.
For WPF - Use the DataGrid.Sorting event call and perform e.Handled = true in its event handler. This stops the datagrid's native sorting. And before e.Handled = true do your custom sort as you like.
For Silverlight - Use the Dispatcher.BeginInvoke() and delgate your task of custom sorting there. Use background dispatcher priority.
Let me know if these help.
精彩评论