我可以删除 EventAggregator 中的重复事件吗?
我有一个非常简单的场景,我无法正常工作。我有 2 个视图,CarView 和 CarWindowView(子窗口)以及相应的 ViewModel。在我的 CarView 中,我有一个 EditButton,它可以打开 CarWindowView(子窗口),我可以在其中编辑 Car 对象字段。
我的问题是我的 CarWindowView ViewModel 中的 DisplayModule 方法被调用太多次...当我第一次按下编辑按钮时,它被调用一次,第二次它被调用两次,第三次它被调用 3 次,所以堡垒...!
CarView ViewModel 构造函数:
Public Sub New(ByVal eventAggregator As IEventAggregator, ByVal con As IUnityContainer, ByVal mgr As ICarManager, ByVal CarService As ICarService)
_Container = con
_CarManager = mgr
_EventAggregator = eventAggregator
'Create the DelegateCommands
NewBtnClick = New DelegateCommand(Of Object)(AddressOf HandleNewCarBtnClick)
EditBtnClick = New DelegateCommand(Of Object)(AddressOf HandleEditCarBtnClick)
End Sub
CarView ViewModel HandleEditCarBtnClick 方法:
Private Sub HandleEditCarBtnClick()
Dim view = New CarWindowView
Dim viewModel = _Container.Resolve(Of CarWindowViewModel)()
viewModel.CurrentDomainContext = DomainContext
viewModel.CurrentItem = CurrentItem
viewModel.IsEnabled = False
view.ApplyModel(viewModel)
view.Show()
_EventAggregator.GetEvent(Of CarCollectionEvent)().Publish(EditObject)
End Sub
CarWindowView ViewModel 构造函数:
Public Sub New(ByVal eventAggregator As IEventAggregator, ByVal con As IUnityContainer, ByVal mgr As ICarManager, ByVal CarService As ICarService)
_Container = con
_CarManager = mgr
_EventAggregator = eventAggregator
_EventAggregator.GetEvent(Of CarCollectionEvent).Subscribe(AddressOf DisplayModule)
End Sub
CarWindowView ViewModel DisplayModule 方法(这是调用太多次的方法):
Public Sub DisplayModule(ByVal param As String)
If param = EditObject Then
IsInEditMode = True
' Logic removed for display reasons here. This logic breaks because it's called too many times.
End If
End Sub
所以,我无法理解如何只能让 EventAggregator 来存储一次单击,并且并非所有我都点击“编辑”按钮。抱歉,如果这没有得到很好的解释!帮助表示赞赏!
I have a quite simple scenario that I cannot get to work correctly. I have 2 views, CarView and CarWindowView (childwindow) with corresponding ViewModels. In my CarView I have an EditButton that that opens CarWindowView (childwindow) where I can edit the Car object fields.
My problem is that the DisplayModule method in my CarWindowView ViewModel is getting called too many times...When I push the edit button first time its getting called once, the second time its getting called twince, the third time its getting called 3 times and so fort... !
CarView ViewModel constructor:
Public Sub New(ByVal eventAggregator As IEventAggregator, ByVal con As IUnityContainer, ByVal mgr As ICarManager, ByVal CarService As ICarService)
_Container = con
_CarManager = mgr
_EventAggregator = eventAggregator
'Create the DelegateCommands
NewBtnClick = New DelegateCommand(Of Object)(AddressOf HandleNewCarBtnClick)
EditBtnClick = New DelegateCommand(Of Object)(AddressOf HandleEditCarBtnClick)
End Sub
CarView ViewModel HandleEditCarBtnClick method:
Private Sub HandleEditCarBtnClick()
Dim view = New CarWindowView
Dim viewModel = _Container.Resolve(Of CarWindowViewModel)()
viewModel.CurrentDomainContext = DomainContext
viewModel.CurrentItem = CurrentItem
viewModel.IsEnabled = False
view.ApplyModel(viewModel)
view.Show()
_EventAggregator.GetEvent(Of CarCollectionEvent)().Publish(EditObject)
End Sub
CarWindowView ViewModel constructor:
Public Sub New(ByVal eventAggregator As IEventAggregator, ByVal con As IUnityContainer, ByVal mgr As ICarManager, ByVal CarService As ICarService)
_Container = con
_CarManager = mgr
_EventAggregator = eventAggregator
_EventAggregator.GetEvent(Of CarCollectionEvent).Subscribe(AddressOf DisplayModule)
End Sub
CarWindowView ViewModel DisplayModule method (this is the method getting called too many times):
Public Sub DisplayModule(ByVal param As String)
If param = EditObject Then
IsInEditMode = True
' Logic removed for display reasons here. This logic breaks because it's called too many times.
End If
End Sub
So, I cannot understand how I can only have the EventAggregator to store just the one single click, and not all my click on the Edit button. Sorry if this is not to well explained! Help appreciated!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
听起来您的 CarWindowViewModel 存在内存泄漏。换句话说,您有该类的多个实例尚未被垃圾收集。在调试器中,查看 GetHashCode。我愿意打赌他们是不同的。
假设您正在使用 Prism 中的 EventAggregator,它应该保留对您的对象的弱引用,所以这不是您的问题。
最有可能的是,您需要确保 ViewModel 完成后,它会取消订阅该事件。另外,看看你是否能找出参考链中的什么使它们保持活力。
It sounds like you have a memory leak of CarWindowViewModel. In other words, you have multiple instances of that class that have not been garbage collected. In the debugger, look at GetHashCode. I'm willing to bet that they are different.
Assuming you are using the EventAggregator from Prism, it is supposed to keep a weak reference to your object, so that is not your problem.
Most likely, you need to ensure that when that ViewModel is done, it unsubscribes from the event. Also, see if you can figure out what in the referance chain is keeping them alive.
我认为 EventAggregator 事件是您希望在其他模块中编写的任何旧视图或视图模型侦听的事件(或不侦听,随心所欲)。如果我有两个视图,它们的操作非常依赖彼此,并且它们始终位于同一逻辑树中,那么我会使用常规的旧 .NET 事件。
我认为只有“即发即忘”类型的事件适合 EventAggregator。我知道 Prism 包中的示例似乎提倡在更紧密耦合的主/细节场景中使用它们,但我真的认为这并不合适(读:过度杀伤)。
尽管这并不能直接解决您的问题(我认为您也存在内存泄漏),但如果您这样组织它,您可能会完全避免此问题。
I consider EventAggregator events to be those that you want any old view or viewmodel written in other modules to listen to (or not, as they please). In the case that I have two views that are very dependent on each other to operate and they always live in the same logical tree, I use regular old .NET events.
It's only the "fire and forget" type of events that I feel are appropriate for the EventAggregator. I know the samples in the Prism package seem to advocate their use in more tightly coupled master/detail scenarios, but I don't really think that appropriate (read: overkill).
Although this doesn't directly address your issue (I'm of the mind that you have a memory leak as well), if you organize it like this you'll likely avoid this issue altogether.