我使用Prism 5.0,並且在配置它以重用現有視圖時遇到問題。每當調用IRegionManager.RequestNavigate(string regionName, Uri source)
時,它將創建一個新視圖,而不是使用先前創建的視圖。奇怪的是,CLRProfiler還指出Prism的區域管理器持有引用所有先前創建的視圖實例,導致內存泄漏。阻止棱鏡創建導航新視圖
我的視圖模型實現了INavigationAware
,並在IsNavigationTarget()
中返回true
,但該方法從未被調用過。我試圖在視圖上實現它,並得到相同的結果。
作爲測試,我在視圖上實現了IActiveAware
,這表明一旦我導航到另一個視圖(我不確定這是否相關),它就會停用。
我發現這個問題:PRISM WPF - Navigation creates new view every time但我的V-VM命名約定匹配那些答案(我使用AutoFac,順便說一句)。
我只找到了解決方法:在視圖模型的INavigationAware.OnNavigatedFrom()
實現中使用NavigationContext.NavigationService.Region.Remove()
從區域中刪除活動視圖。當我這樣做時,Prism的區域經理會發布對該視圖的引用。這有效,但在需要時總是重新創建視圖似乎效率低下。
幾乎所有關於SO的相關問題都要求如何在導航事件上創建新視圖,所以我假設默認行爲是視圖被重用。我需要指針。
編輯
我們使用AutoFac的AutofacExtensions.RegisterTypeForNavigation<T>(this ContainerBuilder builder, string name = null)
註冊的意見。我們確實使用IRegionManager.RequestNavigate()
在視圖之間導航。在ViewModels上實現了INavigationAware
。但是,雖然調用了INavigationAware.OnNavigatedTo()
和OnNavigatedFrom()
,但從未調用IsNavigationTarget()
(即使視圖實現了INavigationAware
,也不調用後者)。
我可以通過在視圖的ctor中設置斷點來檢測到新視圖。 CLRProfiler堆轉儲還顯示區域管理器擁有多次導航到的視圖的實例。 ViewModels只創建一次,因爲它們是以AutoFac作爲單一實例註冊的。
作爲一項臨時措施,我們制定了意見實施IRegionMemberLifetime
,其中KeepAlive
返回false
。這不是非常有效,因爲每次需要時都會重新創建視圖,但它會阻止區域經理堅持以前的視圖。
您需要使用IRegionMemberLifetime和KeepAlive屬性。 –
@AyyappanSubramanian如果視圖實現IRegionMemberLifetime,並且KeepAlive返回true,則區域管理器會保留對視圖的引用,但會在導航到該視圖時創建一個新視圖(如果該視圖未實現IRML,則該視圖必須是默認視圖)。如果KeepAlive返回false,則該視圖將被丟棄,因此需要重新創建。我的問題是如何讓Prism重用原始視圖,所以這不是一個解決方案。 – Drew
我目前有同樣的問題,雖然不是我所有的意見。它似乎是任何低於特定頁面,這是導致我的問題。 – user3265613