Могу ли я удалить дублирующие события в EventAggregator? - PullRequest
1 голос
/ 03 июня 2010

У меня довольно простой сценарий, который я не могу заставить работать правильно. У меня есть 2 представления, CarView и CarWindowView (дочернее окно) с соответствующими ViewModels. В моем CarView у меня есть EditButton, который открывает CarWindowView (дочернее окно), где я могу редактировать поля объекта Car.

Моя проблема в том, что метод DisplayModule в моем CarWindowView ViewModel вызывается слишком много раз ... Когда я нажимаю кнопку редактирования первый раз, когда вызывается один раз, второй раз вызывается twince, в третий раз вызывается 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 для хранения только одного клика, а не всего моего клика по кнопке Edit. Извините, если это не очень хорошо объяснено! Помощь оценена !!

Ответы [ 2 ]

4 голосов
/ 03 июня 2010

Похоже, у вас утечка памяти в CarWindowViewModel.Другими словами, у вас есть несколько экземпляров этого класса, которые не были собраны сборщиком мусора.В отладчике посмотрите на GetHashCode.Я готов поспорить, что они разные.

Предполагая, что вы используете EventAggregator из Prism, он должен сохранять слабую ссылку на ваш объект, поэтому это не ваша проблема.

Скорее всего, вам нужно убедиться, что по завершении этого ViewModel он отписывается от события.Кроме того, посмотрите, сможете ли вы выяснить, что в цепочке ссылок поддерживает их жизнь.

1 голос
/ 03 июня 2010

Я считаю EventAggregator событиями, которые вы хотите, чтобы любой старый view или viewmodel, записанный в других модулях, слушал (или нет, как им угодно). В случае, когда у меня есть два представления, которые очень зависят друг от друга, и они всегда живут в одном и том же логическом дереве, я использую обычные старые события .NET .

Это всего лишь тип событий «запускай и забывай», который, я считаю, подходит для EventAggregator . Я знаю, что образцы в пакете Prism, по-видимому, защищают их использование в более тесно связанных сценариях мастер / деталь, но я не думаю, что это уместно (читай: излишне).

Хотя это напрямую не решает вашу проблему (я думаю, что у вас также есть утечка памяти), если вы организуете ее так, вы, скорее всего, избежите этой проблемы в целом.

...