-1

I have a ListView that is used severally and each case needs to show items of different derived classes of the same abstract class. I want to search the list and remove items from the list. Needless, to say that it would be convenient if I could bind to the base class and encapsulate that in a UserControl.

Concretely, the abstract class

Public MustInherit Class SearchableItem
    Public ReadOnly Property Text As String
End Class

and the derived one

Public Class Series
    Inherits SearchableItem

    Public Property Title As String
    Public Property Desc As String

    Public Overloads ReadOnly Property Text As String
        Get
            Return Title
        End Get
    End Property

End Class

and this shows up in

Public Class SomeAvatar

    Public Property SeriesList As New ObservableCollection(Of Series)

End Class

finally, the UserControl has a dependency property ItemList that the ListView displays.

Public Property ItemList As ObservableCollection(Of SearchableItem)
    Get
        Return GetValue(ItemListProperty)
    End Get

    Set(ByVal value As ObservableCollection(Of SearchableItem))
        SetValue(ItemListProperty, value)
    End Set
End Property

Public Shared ReadOnly ItemListProperty As DependencyProperty =
                       DependencyProperty.Register("ItemList",
                       GetType(ObservableCollection(Of SearchableItem)), GetType(ucListView),
                       New PropertyMetadata(Nothing))

The problem is that ItemList is empty. I have checked all the Loaded events of parents of the UserControl and they all have the collection complete. I then passed the collection as part of the DataContext of the UserControl and got the error that said Unable to cast observablecollection(of base) to observablecollection(of derived) (paraphrased).

Isn't a collection of dogs also a collection of animals? I have to be missing some basic thing or is this something to do with WPF?

Ian Botham
  • 113
  • 4
  • 11
  • 1
    _"Isn't a collection of dogs also a collection of animals?"_ -- no, it's not. Not when you're allowed to _add_ an animal to the collection. A collection of animals will let you put a cat into it. If you take a collection of dogs and act like it's just a collection of animals, then you can put a cat into your collection of dogs. Not good. See duplicates. – Peter Duniho Oct 20 '20 at 02:29
  • Does this answer your question? [Casting List<> of Derived class to List<> of base class](https://stackoverflow.com/questions/3720751/casting-list-of-derived-class-to-list-of-base-class) – Peter Duniho Oct 20 '20 at 02:31
  • See also https://stackoverflow.com/questions/16966961/cannot-convert-from-listderivedclass-to-listbaseclass, and pretty much any question that has an answer discussing generic type variance. – Peter Duniho Oct 20 '20 at 02:31

1 Answers1

1

This answer to a very similar question explains why this isn't allowed.

The short answer, is you can't treat a writable collection of Series as a writable collection of SearchableItem, because a collection of SearchableItem should be allowed to contain any object derived from SearchableItem, while a collection of Series should only be allowed to contain Series objects.

The shorter answer, is you can read an ObservableCollection<Series> as if it were an ObservableCollection<SearchableItem>, but you can't write to it as such.

If ItemList only needs to read from the collection, then you could use IEnumerable<SearchableItem>, which would you to assign value of ObservableCollection<Series>.

Keith Stein
  • 6,235
  • 4
  • 17
  • 36