dotnet/wpf · error · ArgumentException
SR.CannotDetermineSortByPropertiesForCollection
Error message
SR.CannotDetermineSortByPropertiesForCollection
What it means
When converting WPF SortDescriptions to .NET ListSortDescriptions for a BindingListCollectionView, the view obtains the item property descriptors from the source list. If it cannot determine any sort-by properties (the item type has no properties, or the list provides no item type information), it throws ArgumentException with SR.CannotDetermineSortByPropertiesForCollection.
Solutions
- Sort the underlying collection directly (e.g. with OrderBy and reassign) instead of using SortDescriptions.
- Bind to a collection of a type with public properties (a view-model or row type) so property descriptors can be resolved.
- Implement ITypedList on the custom list to supply the item PropertyDescriptorCollection.
- For empty collections, pre-populate or use a typed view-model collection so reflection can find properties.
Example fix
// before
var view = (BindingListCollectionView)CollectionViewSource.GetDefaultView(new List<int>());
view.SortDescriptions.Add(new SortDescription("Value", ListSortDirection.Ascending)); // throws
// after
var source = new ObservableCollection<MyRow>();
var view2 = CollectionViewSource.GetDefaultView(source);
view2.SortDescriptions.Add(new SortDescription("Value", ListSortDirection.Ascending)); Defensive patterns
Strategy: validation
Validate before calling
var props = item != null ? TypeDescriptor.GetProperties(item.GetType()) : null;
if (props == null || props.Count == 0)
throw new InvalidOperationException("item type exposes no sortable properties"); Type guard
bool isSortableCollection<T>(IEnumerable<T> c) => typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Length > 0;
Try / catch
try { view.SortDescriptions.Add(sd); }
catch (ArgumentException) { /* sort the underlying collection directly */ } Prevention
- Avoid SortDescriptions on collections of primitives
- Bind to typed view-model collections, not List<object>
- Implement ITypedList on custom lists to expose item properties
When it happens
Trigger: Calling view.SortDescriptions.Add(...) (or CustomSort-free sorting) on a BindingListCollectionView whose source is a list of a type with no public instance properties, or whose IBindingList/ITypedList cannot supply a PropertyDescriptorCollection (e.g. list of primitives, empty list with no type info, non-ITypedList custom list of object).
Common situations: Binding to List<int>, List<string> or other primitive collections and then setting SortDescriptions with a property path; binding to an empty collection whose item type cannot be reflected; DataGrid column auto-sorting over such a source.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.Format(SR.PropertyToSortByNotFoundOnType, typeName…
- SR.Format(SR.CannotSortView, view)
- SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "CustomSort")
- SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Sorting")
- SR.Format(SR.PropertyNotBindable, dp.Name)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7f35ea9f4a53325e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingListCollectionView.cs:2195
PropertyDescriptorCollection pdc;
ITypedList itl;
Type itemType;
if ((itl = InternalList as ITypedList) != null)
{
pdc = itl.GetItemProperties(null);
}
else if ((itemType = GetItemType(true)) != null)
{
pdc = TypeDescriptor.GetProperties(itemType);
}
else
{
pdc = null;
}
if ((pdc == null) || (pdc.Count == 0))
throw new ArgumentException(SR.CannotDetermineSortByPropertiesForCollection);
ListSortDescription[] sortDescriptions = new ListSortDescription[sorts.Count];
for (int i = 0; i < sorts.Count; i++)
{
PropertyDescriptor dd = pdc.Find(sorts[i].PropertyName, true);
if (dd == null)
{
string typeName = itl.GetListName(null);
throw new ArgumentException(SR.Format(SR.PropertyToSortByNotFoundOnType, typeName, sorts[i].PropertyName));
}
ListSortDescription sd = new ListSortDescription(dd, sorts[i].Direction);
sortDescriptions[i] = sd;
}
return new ListSortDescriptionCollection(sortDescriptions);
}
#region GroupingView on GitHub (pinned to 81131a70a4)