我有添加处理程序的问题:我解释
这是中介类
Public Class ContratClassiqueViewModel
Implements IMediatorContratClassique
Public objucPTClassiqueViewModel As ucPTClassiqueViewModel
#Region "Constructors"
Sub New(ByVal CtxViewModel As CtxViewModel, ByVal ucPlancheTravaux As ucPTClassiqueViewModel)
objCtxViewModel = CtxViewModel
objucPTClassiqueViewModel = ucPlancheTravaux
objucPTClassiqueViewModel.AddHandlers()
AddingHandlers()
End Sub
Sub New()
objucPTClassiqueViewModel = New ucPTClassiqueViewModel(True)
objucPTClassiqueViewModel.AddHandlers()
AddingHandlers()
End Sub
#End Region
Private Sub AddingHandlers()
AddHandler objucPTClassiqueViewModel.ChangeDateRealisation, AddressOf OnChangeDateRealisation
End Sub
Private Sub OnChangeDateRealisation(ByVal DatRealisation As Date?)
Messagebox.Show("Raised")
End Sub
End Class
另一堂课:
Public Class ucPTClassiqueViewModel
Implements IMediatorContratClassique
Public objucParamPTViewModel As ucParamPTViewModel
Sub New()
End Sub
Sub New(ByRef flag As Boolean)
objucParamPTViewModel = New ucParamPTViewModel
End Sub
Public Sub AddHandlers()
AddHandler objucParamPTViewModel.ChangeDateRealisation, AddressOf OnChangeDateRealisation
End Sub
Private Sub OnChangeDateRealisation(ByVal DatRealisation As Date?)
RaiseEvent ChangeDateRealisation(DatRealisation)
End Sub
End class
问题是:当程序使用类ContratClassiqueViewModel
的默认构造函数时,它可以工作,但如果它使用其他构造函数:
Sub New(ByVal CtxViewModel As CtxViewModel, ByVal ucPlancheTravaux As ucPTClassiqueViewModel)
objCtxViewModel = CtxViewModel
objucPTClassiqueViewModel = ucPlancheTravaux
objucPTClassiqueViewModel.AddHandlers()
AddingHandlers()
End Sub
方法:
Private Sub OnChangeDateRealisation(ByVal DatRealisation As Date?)
Messagebox.Show("Raised")
End Sub
永远不会达到,因为它似乎将处理程序添加到另一个ucPTClassiqueViewModel
实例。所以我需要知道:
答案 0 :(得分:1)
要在类之间共享viewmodel,首先应创建一个共享的viewmodel,然后将所有需要它/共享它的类附加到同一个viewmodel。
为此,您可以创建一个Factory方法,该方法知道viewmodel(如果需要,还会创建一个尚未存在的视图模型,或警告用户尚未存在视图模型)。然后,工厂方法将viewmodel附加到需要它的类。
然后,在viewmodel上抛出的任何事件都将迭代到您的侦听器
Factory类的示例可以是以下
Public Class ViewModelFactory
Public Shared Property ViewModel As IViewModel
Public Shared Function Create(Of T As IHaveViewModel)() As T
Dim newItem As T = Nothing
Try
newItem = Activator.CreateInstance(Of T)()
If ViewModel Is Nothing Then
Throw New InvalidOperationException("Cannot create items that have a viewmodel before the viewmodel was created!")
End If
' assign the viewmodel
newItem.ViewModel = ViewModel
Catch ex As Exception
Console.WriteLine("Error creating new {0}\r\nMessage: {1}\r\nStacktrace: {2}", GetType(T).FullName, ex.Message, ex.StackTrace)
End Try
Return newItem
End Function
End Class
这个会创建基于接口IHaveViewModel
的类(看起来像这样,例如)
Public Interface IHaveViewModel
Property ViewModel As IViewModel
End Interface
为了简化侦听器的实现,您可以创建一个为您附加任何侦听器的抽象类,并将DateChangedEvent转发到可覆盖的方法(或者在我的情况下,一个抽象方法,必须由任何类实现继承它)。可以使用dispose方法确保在处理类
时删除处理程序Public MustInherit Class WatcherClass
Implements IHaveViewModel, IDisposable
Private _viewModel As IViewModel
Public Property ViewModel As IViewModel Implements IHaveViewModel.ViewModel
Get
Return _viewModel
End Get
Set(value As IViewModel)
If Object.ReferenceEquals(_viewModel, value) Then
Return
End If
RemoveModelListeners()
_viewModel = value
AddModelListeners()
End Set
End Property
Private Sub AddModelListeners()
If ViewModel Is Nothing Then
Return
End If
AddHandler ViewModel.DateChangedEvent, AddressOf Me.OnDateInModelChanged
End Sub
Private Sub RemoveModelListeners()
If ViewModel Is Nothing Then
Return
End If
RemoveHandler ViewModel.DateChangedEvent, AddressOf Me.OnDateInModelChanged
End Sub
Protected MustOverride Sub OnDateInModelChanged(sender As Object, changeDate As DateTime?)
Private disposedValue As Boolean
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
RemoveModelListeners()
End If
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
End Class
然后从这个实现继承的任何类必须实现DateChanged处理程序方法,因为这两个类都有(例如)
Public Class ImplementedWatcher
Inherits WatcherClass
Protected Overrides Sub OnDateInModelChanged(sender As Object, changeDate As Date?)
Console.WriteLine("Hello world from {0}", Me.GetType().FullName)
End Sub
End Class
Public Class SecondWatcher
Inherits WatcherClass
Protected Overrides Sub OnDateInModelChanged(sender As Object, changeDate As Date?)
Console.WriteLine("This one also heard me :)")
End Sub
End Class
IViewModel
可能如下所示
Public Delegate Sub DateChangedEventHandler(sender As Object, changeDate As DateTime?)
Public Interface IViewModel
Event DateChangedEvent As DateChangedEventHandler
End Interface
实施可能是以下
Public Class ViewModel
Implements IViewModel
Public Event DateChangedEvent(sender As Object, changeDate As DateTime?) Implements IViewModel.DateChangedEvent
Private _date As DateTime?
Public Property ChangeDate As DateTime?
Get
Return _date
End Get
Set(value As DateTime?)
If Object.Equals(value, _date) Then
Return
End If
_date = value
RaiseDateChanged(_date)
End Set
End Property
Protected Overridable Sub RaiseDateChanged(changeDate As DateTime?)
RaiseEvent DateChangedEvent(Me, changeDate)
End Sub
Public Sub New()
' ViewModel
End Sub
End Class
测试这些课程,以及他们如何互动"彼此,你可以使用这个主要方法(控制台程序)
Sub Main()
Dim viewModel As ViewModel = New ViewModel()
ViewModelFactory.ViewModel = viewModel
Dim watcher As IHaveViewModel = ViewModelFactory.Create(Of ImplementedWatcher)()
Dim secondWatcher As IHaveViewModel = ViewModelFactory.Create(Of SecondWatcher)()
Console.WriteLine("Setting date to today")
viewModel.ChangeDate = DateTime.Now
Console.WriteLine("Setting date to tomorrow")
viewModel.ChangeDate = DateTime.Now.AddDays(1)
Console.WriteLine("Setting date to next week")
DirectCast(watcher.ViewModel, ViewModel).ChangeDate = DateTime.Now.AddDays(7)
DirectCast(watcher, IDisposable).Dispose()
DirectCast(secondWatcher, IDisposable).Dispose()
Console.ReadLine()
End Sub
这意味着最终所有具有共享viewmodel的类也应该通过Factory方法创建,这个类可以将viewmodel添加到潜在的侦听器。直接从ImplementedWatcher
或SecondWatcher
创建的任何类,当他们获得分配的ViewModel(通过属性)时,也会监听
通过在Watcher类上将ViewModel设置为Nothing,将删除处理程序,或者您可以通过处理Watcher类来执行此操作
我希望能让您继续执行您的计划吗?
作为一个注释,您还可以将INotifyPropertyChanged
接口实现到IViewModel类中,然后您可以收到有关ViewModel中所有更改的警告(如果您愿意)并让侦听器决定它们属于哪些属性应该做出反应,那么你就不必创造大量的活动。