For Avalonia.Controls.ListBox for Items Property, Support for IList<T> without non-generic IList
See original GitHub issueDescribe the bug For a DataContext View-Model that has Specialized Collections, collections may implement the IList<T> or IReadOnlyList<T> interfaces, neither of which implements non-generic IList interface.
Any such collections when they also implement INotifyCollectionChanged cause assignment of the DataContext involved throw an exception stating, correctly, that the collection in question does not implement IList, which is correct - it does not.
My expectations were that ListBoxes would work with generic collections, not only collections that implement IList
To Reproduce Steps to reproduce the behavior:
1.) Create a ViewModel that implements INPC, create a collection that implements IList<T> or IReadOnlyList<T> and INotifyCollectionChanged but does not implement IList 2.) Assign the collection as the DataContext of a Window or view such that you have a ListBox that has its Items bound to the collection. 3.) Observe the argument exception in question.
Expected behavior The expectation is that ListBox classes should be able to display the items of both IList<T> and IReadOnlyList<T> and update their views as the collections change so long as they implement INotifyCollectionChanged
Screenshots Not really relevant to this.
Desktop (please complete the following information):
Also not really relevant to this either.
Additional context
Could ItemsSourceView be modified around Line 49 to check before throwing an exception if Source is IReadOnlyList<object>? In my testing _qc2 is IReadOnlyList<object>
returned true
for instances of a class definition internal class QuickCollectionWithoutIList : IReadOnlyList<QuickModel>, INotifyCollectionChanged
But that’s incompatible with the non-generic IList interface and can’t be cast to IList properly. What a pain! And the Inner
property of ItemsSourceView needs filling.
I feel like this is perhaps stepping onto an earlier pain-point of the .Net BCL similar to the generic IEnumerable<T> and the non-generic IEnumerable. 🙃
I suppose you could if you wanted to you could do some interesting castings, but I don’t know if there are any IList implementing classes that don’t also implement IReadOnlyList<T> - and all IReadOnlyList<T> are castable to IReadOnlyList<object> because of the rules of Covariance. But after checking the IList documentation there’s plenty of types out there that implement IList but don’t implement IReadOnlyList<T> - what a pain!
Would it be too much to have some sort of interface of an indexing provider, that could have implementations that use either IList as a parameter, or IReadOnlyList<T>, and all it needs to do is provide a method of indexing the lists?
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:21 (21 by maintainers)
Top GitHub Comments
A user may want to display the contents of a simple enumerable and then refresh the UI manually when they know/judge that it has changed. But since a copy was taken, this won’t work.
The case of an infinite enumerable is a pain, though you could throw an exception after enumerating
int32.MaxValue
times. I suspect that theList<T>
constructors currently in use do this already.I don’t think
IEnumerable
can be cast toIList
in any case. The enumeration may be infinite, whileIList
may not.