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

  1. Sort the underlying collection directly (e.g. with OrderBy and reassign) instead of using SortDescriptions.
  2. Bind to a collection of a type with public properties (a view-model or row type) so property descriptors can be resolved.
  3. Implement ITypedList on the custom list to supply the item PropertyDescriptorCollection.
  4. 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

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


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 Grouping

View on GitHub (pinned to 81131a70a4)