'Sorting' is not allowed during an AddNew or EditItem transaction.
This stackoverflow discussion has the correct answer to my issue, but it isn't marked as the answer for now. So I would like to list it here and explain a bit, and hope this can help somebody out.
Background
We had a datagrid in a customized control, which is used to select files. The control has a ViewModel class as its DataContext and can load different ViewModel classes. The control itself will stay in memory, but the ViewModel will get disposed every time the view is closed.
It works fine most of the time. However, if users sort the datagrid by clicking a column header and then select a file by double click, and next time when the view is opened, the exception:
'Sorting' is not allowed during an AddNew or EditItem transaction.
will be thrown.
I checked the stack trace of the exception and saw the exception came from System.Windows.Data.ListCollectionView.SortDescriptionsChanged(). When using ILSpy to check ListCollectionView class, we can see this code in SortDescriptionsChanged()
if (this.IsAddingNew || this.IsEditingItem)
{
throw new InvalidOperationException(Resx.GetString("CollectionView_MemberNotAllowedDuringAddOrEdit", new object[]
{
"Sorting"
}));
}
{
throw new InvalidOperationException(Resx.GetString("CollectionView_MemberNotAllowedDuringAddOrEdit", new object[]
{
"Sorting"
}));
}
Solutions
ptsivakumar listed 2 solutions which both are good in my case. I listed the solutions here in case that thread is not accessable.
1) Add CommitNew() and CommitEdit()
This should be put in a proper place suitable for your specific case. In my case, I put it in the view Close event handler:
var dataView =
(ListCollectionView)CollectionViewSource.GetDefaultView(DataGrid_Files.ItemsSource);
if (dataView.IsEditingItem)
dataView.CommitEdit();
if (dataView.IsAddingNew)
dataView.CommitNew();
if (dataView.IsEditingItem)
dataView.CommitEdit();
if (dataView.IsAddingNew)
dataView.CommitNew();
2) Add IsReadOnly="True" to the datagrid control, also remember to add CanUserAddRows="False"
Both solutions are working well. The reason is when the datagrid is double clicked, it will enter the edit mode, but the sorting feature doesn't allow the datagrid in Adding New or Editing mode when a sorting event happens. So the first solution will commit changes and bring the datagrid to a normal mode. The second solution works because the settings will keep the datagrid always in a normal mode. Double click is ignored.
2 comments:
Thanks so much for this solution! worked well for me when many other attempts failed.
Same here!
I have a field on each item that gives the sort order.
If I recalculate that field as a result of an edited or added item, I was not allowed to resort the contents while I was still in the event handler (since commit probably gets called upon return).
Your snippet above gave me the possibility to commit while still in the event handler, and then perform reloading according to the new sort order.
Thanks!
Post a Comment