I am trying to create a list onscreen of all animals in a database in an MVVM WPF application, but this list must contain properties that are specific to the animals' respective sex (represented by a class).
The model consists of Male
and Female
classes inheriting from MustInherit Animal
. Following this example, The ViewModel is therefore also split into MaleViewModel
and FemaleViewModel
which both inherit from a generic MustInherit AnimalViewModel
, below
Public MustInherit Class AnimalViewModel(Of T as Animal)
Inherits GalaSoft.MvvmLight.ViewModelBase
Public Property Animal As T
Protected Sub New(NewAnimal as T)
Me.Animal = NewAnimal
End Sub
Public Overrides Function ToString() as String
Return String.Format("{1}{2} ""{3}"" | {4}",
Me.Animal.RightEarTag,
Me.Animal.LeftEarTag,
Me.Animal.ShortName,
Me.SexIdentifierName)
End Function
'Makes a distinction between "bull", "cow", "steer", "heifer",
'or other classes as needed
Public MustOverride Function SexIdentifierName as String
End Class
Public Class MaleViewModel
Inherits AnimalViewModel(Of Male)
Public Sub New(AnAnimal as Male)
MyBase.New(AnAnimal)
End Sub
Public Overrides Function SexIdentifierName as String
'Logic goes here
End Function
End Class
I have also created an AnimalListWorkspace
ViewModel, with an AnimalList
property that is bound to a UserControl on the View. I would like to add the correct type of ViewModel to this list, but it is invalid to cast a base type to an inherited type, as I tried in the following code.
Public Class AnimalListWorkspace
Inherits WorkspaceViewModel
Public ReadOnly Property AnimalList as IEnumerable(Of AnimalViewModel(Of Animal))
Get
Dim animalVmList = New List(Of AnimalViewModel(Of Animal))
For Each an in AnimalDatabase.Animals
If TypeOf an Is Male Then
animalVmList.Add(New MaleViewModel(Ctype(an, Male)))
ElseIf TypeOf an Is Female Then
animalVmList.Add(New FemaleViewModel(Ctype(an, Female)))
Else
Throw New InvalidCastException("Unknown sex/type of animal")
End If
Next
Return animalVmList
End Get
End Property
What is the best way to deal with these computed, MustOverride properties? I have considered
Moving their implementation up to the
AnimalViewModel
Altering the database object to retrieve
Males
andFemales
specifically
These solutions might work for this example because there are so few inherited members, but they both seem tightly-coupled and hard to refactor later.