首页 > 解决方案 > 如何处理继承的 ViewModel 中的 MustOverride(虚拟)属性

问题描述

我正在尝试在 MVVM WPF 应用程序的数据库中创建一个所有动物的列表,但该列表必须包含特定于动物各自性别的属性(由一个类表示)。

该模型由MaleFemale继承自 的类 组成MustInherit Animal在这个示例之后,ViewModel 也因此被拆分为MaleViewModel并且FemaleViewModel都继承自一个泛型MustInherit AnimalViewModel,如下

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

我还创建了一个AnimalListWorkspaceViewModel,其AnimalList属性绑定到 View 上的 UserControl。我想将正确类型的 ViewModel 添加到此列表中,但将基类型强制转换为继承类型是无效的,正如我在以下代码中尝试的那样。

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

处理这些计算的 MustOverride 属性的最佳方法是什么?我考虑过

  1. 将它们的实施转移到AnimalViewModel

  2. 更改数据库对象以检索MalesFemales特别是

这些解决方案可能适用于本示例,因为继承的成员很少,但它们似乎都是紧密耦合的,并且以后难以重构。

标签: c#wpfvb.netmvvmpolymorphism

解决方案


类型参数似乎没有必要。基类的构造函数接受一个Animal并且只知道动物。Male是一种特定的类型Animal。以下应该可以工作,即您可以将任何类型的特定添加AnimalViewModelList(Of AnimalViewModel).

查看型号:

Public MustInherit Class AnimalViewModel
    Inherits GalaSoft.MvvmLight.ViewModelBase

    Public Property Animal As Animal

    Protected Sub New(NewAnimal As Animal)
        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

    Public MustOverride Function SexIdentifierName() As String

End Class

Public Class MaleViewModel
    Inherits AnimalViewModel

    Public Sub New(AnAnimal As Male)
        MyBase.New(AnAnimal)
    End Sub

    Public Overrides Function SexIdentifierName() As String
        Return "Male"
    End Function
End Class

楷模:

Public Class Animal
    Public Property RightEarTag As String
    Public Property LeftEarTag As String
    Public Property ShortName As String
End Class

Public Class Male
    Inherits Animal

End Class

工作区:

Public Class AnimalListWorkspace

    Public ReadOnly Property AnimalList As IEnumerable(Of AnimalViewModel)
        Get
            Dim animalVmList = New List(Of AnimalViewModel)

            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
End Class

推荐阅读