2010-06-03 43 views
1

我有一个很简单的情况,我无法正常工作。我有2个视图,CarView和CarWindowView(childwindow)以及相应的ViewModels。在我的CarView中,我有一个EditButton,它可以打开CarWindowView(childwindow),我可以在其中编辑Car对象字段。我可以删除EventAggregator中的重复事件吗?

我的问题是我的CarWindowView ViewModel中的DisplayModule方法被调用了太多次...当我第一次按下编辑按钮时,它被调用一次,第二次它被调用twince,第三次它获取叫3次等等要塞......!

Carview会视图模型构造:

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会视图模型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视图模型构造:

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视图模型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存储只有一个单一的点击,而不是我所有的点击编辑按钮。对不起,如果这不是很好解释!帮助赞赏!

回答

4

这听起来像你有一个CarWindowViewModel内存泄漏。换句话说,你有这个类的多个实例没有被垃圾回收。在调试器中,查看GetHashCode。我敢打赌,他们是不同的。

假设您使用Prism中的EventAggregator,它应该保留对您的对象的弱引用,所以这不是您的问题。

最有可能的是,您需要确保当ViewModel完成后,它会退出该事件。此外,看看你是否能够弄清楚参加连锁店让他们活着的内容。

+0

你可能很对,我会调查。 你是什么意思; “在调试器中,看看GetHashCode” - 什么是GetHashCode,在调试过程中我怎么看? 另外我在每个EditBtn点击运行这行代码:_Container.Resolve(的CarWindowViewModel)() 这可能导致行为? – Mcad001 2010-06-03 11:05:35

+1

当您在该类的某个方法的调试器中时,在监视窗口中输入this.GetHashCode()。它会为你的班级提供一个唯一的ID。使用这个,你可以找出你正在查看哪个实例。一个类似的机制是将其添加到监视窗口并选择“Make ID”,并且它会给它一个更加漂亮的ID来跟踪它。 如果您使用容器来解析ViewModel,则可以考虑将其配置为单个生命周期......这种方式只能创建一次。 寻找你在课堂上所吸引的事件。这是泄漏的常见地点。 – 2010-06-03 13:18:53

+0

你是对的Brian。 取消订阅活动解决了我的问题。 – Mcad001 2010-06-08 09:45:48

1

我认为EventAggregator事件是您希望在其他模块中写入任何旧视图或视图模型以听取(或不是,因为他们喜欢)的事件。如果我有两个非常依赖于彼此操作的视图,并且他们总是生活在同一个逻辑树中,我使用常规的旧.NET事件

这只是我觉得适合EventAggregator的“火和忘记”类型的事件。我知道Prism包中的示例似乎主张将它们用在更紧密耦合的主/细节场景中,但我并不认为这是合适的(阅读:矫枉过正)。

尽管这不能直接解决您的问题(我也在意识到您也有内存泄漏),但如果您像这样组织它,则可能完全避免此问题。