2010-06-03 46 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包中的示例似乎主張將它們用在更緊密耦合的主/細節場景中,但我並不認爲這是合適的(閱讀:矯枉過正)。

儘管這不能直接解決您的問題(我也在意識到您也有內存泄漏),但如果您像這樣組織它,則可能完全避免此問題。