在不同集合中共享视图模型实例

时间:2021-03-02 22:50:50

标签: vb.net mvvm

是否有在不同集合对象之间创建和共享视图模型实例的最佳实践?例如,下面是一个 SchoolClass 类的场景,它们都具有 Student 对象的集合:

Public Class Student
    Public Property FirstName As String
    Public Property LastName As String
    Public Property Id As Integer
End Class

Public Class [Class]
    Public Property Id As Integer
    Public Property Name As String
    Public Property Students As New Dictionary(Of Integer, Student)

    Public Event StudentAdded(sender As Object, e As StudentEventArgs)

    Public Sub AddStudent(student As Student)
        If Not Students.ContainsKey(student.Id) Then
            Students.Add(student.Id, student)
            RaiseEvent StudentAdded(Me, New StudentEventArgs(student))
        End If
    End Sub

End Class

Public Class School

    Public Property Classes As New Dictionary(Of Integer, [Class])
    Public Property Students As New Dictionary(Of Integer, Student)

    Public Event ClassAdded(sender As Object, e As EventArgs)
    Public Event StudentAdded(sender As Object, e As StudentEventArgs)

    Public Sub AddClass([class] As [Class])
        If Not Classes.ContainsKey([class].Id) Then
            Classes.Add([class].Id, [class])
            RaiseEvent ClassAdded(Me, EventArgs.Empty)
        End If
    End Sub

    Public Sub AddStudent(student As Student)
        If Not Students.ContainsKey(student.Id) Then
            Students.Add(student.Id, student)
            RaiseEvent StudentAdded(Me, New StudentEventArgs(student))
        End If
    End Sub

End Class
Public Class StudentEventArgs
    Inherits EventArgs

    Public Property Student As Student

    Public Sub New(student As Student)
        Me.Student = student
    End Sub

End Class

SchoolClass 创建视图模型时,两者最终都可能为相同的 Student 对象创建视图模型:

Public Class SchoolViewModel
    Inherits BaseViewModel

    Private WithEvents _school As School

    Public Sub New(school As School)
        _school = school
    End Sub

    Public Property Students As New ObservableCollection(Of StudentViewModel)
    Public Property Classes As New ObservableCollection(Of ClassViewModel)

    Private Sub _school_StudentAdded(sender As Object, e As StudentEventArgs) Handles _school.StudentAdded
        ' Create a new View Model for the Student
        Students.Add(New StudentViewModel(e.Student))
    End Sub

End Class

Public Class ClassViewModel
    Inherits BaseViewModel

    Private WithEvents _class As [Class]

    Public Sub New([class] As [Class])
        _class = [class]
    End Sub

    Public Property Students As New ObservableCollection(Of StudentViewModel)

    Private Sub _class_StudentAdded(sender As Object, e As StudentEventArgs) Handles _class.StudentAdded
        ' Create a new View Model or try to get the one created by the SchoolViewModel?
        Students.Add(New StudentViewModel(e.Student))
    End Sub

End Class

Public Class StudentViewModel
    Inherits BaseViewModel

    Private _student As Student

    Public Sub New(student As Student)
        _student = student
        With _student
            Me.FirstName = .FirstName
            Me.LastName = .LastName
            Me.Id = .Id
        End With
    End Sub

    Public Property FirstName As String
    Public Property LastName As String
    Public Property Id As Integer

End Class

我的问题是关于在 StudentViewModelSchoolViewModel ClassViewModel 事件处理程序中创建 StudentAdded 实例。让我们假设学生首先被添加到 School 中,然后被分配到他们的班级。 StudentViewModel 非常简单,创建重复项可能不是问题,但如果已经在 SchoolViewModel 中为同一个学生创建了视图模型,这似乎很浪费。

如果我想分享 SchoolViewModelStudentViewModel,最佳做法是什么?

  1. 在创建新的 SchoolViewModel 时传递对 StudentsClassViewModel ObservableCollection 的引用?
  2. 创建一些 GetStudentViewModelDelegate 函数?
  3. 创建 SharedStudentViewModel 集合?

我通常会尝试限制对象之间的引用,在这个例子中创建新的视图模型将是一个权衡。

1 个答案:

答案 0 :(得分:1)

虽然我无法专门在 VB 方面提供帮助,但您可能最好研究一下 GENERICS。

https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/generic-types

这是一种创建更多顶级类的方法,其中内部操作代表给定的“类型”。例如:学生、学校、主题(而不是名为 [Class] 的班级类型。我只看到下游所有类型的混淆。

这篇文章涵盖了一些基础知识,但我认为这正是您所需要的。您也希望事物和函数的上下文是通用的,因此无论您想要什么“类型”,您都可以嵌套通用功能。

例如,对于您的每个学生、班级、学校,您都有一个“AddStudent”、“AddClass”、“AddSchool”或类似名称。如果你有一个带有“Add”方法的泛型,那么它就会有一次“Add”占位符/操作。然后,如果你有这个 ViewModel 作为“Student”类型工作,另一个“School”有一个 ViewModel“Student”的实例,你可以做类似的事情

SchoolObject.StudentObject.Add()
vs
SchoolObject.Add()

“Of”类型也可以声明为基于“接口”或某些 parentClassType 限定的类类型。因此,如果您有一个对所有学生、班级(学科)、学校通用的基类,那么您可以将通用应用到 INTERFACE。所以,请原谅我在 VB 的基本能力。

https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/interfaces/walkthrough-creating-and-implementing-interfaces

希望这可以帮助您利用一个概念来更好地满足您不熟悉的需求。

相关问题