Skip to content

BindingSource.Sort fails with custom IBindingListView in .NET 9 (worked in .NET 8) #13061

Closed
@JimWilcox3

Description

@JimWilcox3

Description

BindingSource.Sort fails with custom IBindingListView in .NET 9 (worked in .NET 8)

Reproduction Steps

Create a custom class implementing IBindingListView and IBindingList, inheriting from BindingList (see code in Other Information).

Set it as the DataSource of a BindingSource.

Set BindingSource.Sort = "Property desc" where Property exists in the item type.

Observe the result.

Expected behavior

In .NET 8, BindingSource.Sort calls IBindingList.ApplySort, sorting the list.

The list is sorted, and no exception is thrown.

Actual behavior

In .NET 9, it throws "Sort string contains a property that is not in the IBindingList" without calling IBindingList.ApplySort.

Regression?

It worked in .net8

Known Workarounds

In my actual application, I can sort the BindingListView before I pass it to the BindingSource and it works. Once the BindingSource is bound to the DataGridView, you can sort by clicking the column headers. I tried sorting the BindingSource after it was passed to the DataGridView and the Sort property still threw the above error. The problem seems to be with setting the Sort property of the BindingSource.

Configuration

.NET 9.0

Windows 11

x64

Other information

namespace WinFormsApp1
{
using System.ComponentModel;
using System.Windows.Forms;

public class Journal
{
    public DateTime IDate { get; set; }
    public string Name { get; set; }
}

public class SimpleBindingList<T> : BindingList<T>, IBindingListView
{
    public SimpleBindingList(List<T> list) : base(list) { }

    // IBindingListView members
    public void ApplySort(ListSortDescriptionCollection sorts)
    {
        Console.WriteLine("IBindingListView.ApplySort called");
        // Minimal implementation for multi-column sort
    }

    public string Filter { get => ""; set { } }
    public void RemoveFilter() { }
    public ListSortDescriptionCollection SortDescriptions => new ListSortDescriptionCollection();
    public bool SupportsAdvancedSorting => true;
    public bool SupportsFiltering => true;

    // IBindingList overrides
    protected override bool SupportsSortingCore => true;
    protected override bool IsSortedCore => false;
    protected override PropertyDescriptor SortPropertyCore => null;
    protected override ListSortDirection SortDirectionCore => ListSortDirection.Ascending;

    protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection dir)
    {
        Console.WriteLine($"ApplySortCore called with {prop?.Name} {dir}");
        if (prop == null) throw new ArgumentNullException(nameof(prop));
        // Minimal sort logic (not needed to repro the error)
        List<T> list = Items as List<T>;
        if (list != null)
        {
            list.Sort((x, y) => Comparer<object>.Create((a, b) => a.ToString().CompareTo(b.ToString()))
                .Compare(prop.GetValue(x), prop.GetValue(y)));
        }
    }

    // Explicit IBindingList implementation
    void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
    {
        Console.WriteLine($"IBindingList.ApplySort called with {property?.Name} {direction}");
        ApplySortCore(property, direction);
    }
}

class Program
{
    static void Main()
    {
        var result = new List<Journal>
    {
        new Journal { IDate = DateTime.Now, Name = "A" },
        new Journal { IDate = DateTime.Now.AddDays(-1), Name = "B" }
    };

        var list = new SimpleBindingList<Journal>(result);
        var bs = new BindingSource { DataSource = list };
        try
        {
            bs.Sort = "IDate desc"; // Should hit ApplySortCore or fail with error
            foreach (Journal item in bs)
            {
                Console.WriteLine($"{item.IDate} - {item.Name}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

}

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions