2016-08-19 91 views
0

我在棱鏡只有2天知道,所以不要判斷我的任何錯誤的假設,當試圖解釋以下navigaton問題。棱鏡請求導航的行爲

假設我們只有1個區域和2個不同的視圖。視圖A從自定義RegionBehavior啓動時加載到該區域。我使用的是在該行爲中的RegionManager上的RequestNavigate。我沒有找到任何更好的解決方案來設置初始視圖,但這不是這裏的主要觀點。

現在我們在每個視圖上都有一個按鈕來導航到另一個視圖。這些命令在每個ViewModel上執行並再次調用RequestNavigate。 我使用常量來註冊容器(Autofac)的導航視圖,我使用相同的常量來調用RequestNavigate。 一切正常,一見鍾情。但後來我意識到每次切換視圖時,都會創建一個新的視圖和視圖模型。更糟糕的是,RegionManager仍然保存着所有先前的引用,這似乎是內存泄漏。我可以切換到現在將我的視圖註冊爲單例,但我仍然不明白爲什麼RegionManager會以這種方式工作。爲什麼他不知道他已經知道一個觀點,我請求導航並激活該觀點而不是創建新觀點?我還有什麼使用常量作爲名稱呢?

然後我發現這個帖子PRISM WPF - Navigation creates new view every time,事實上這解決了這個問題。只要我使用該類型的名稱來註冊視圖,一切都按預期工作。視圖模型和視圖模型是在第一次使用時創建的,然後在再次請求導航時重複使用。

我仍然可以實現IRegionMemberLifetime並在KeepAlive上返回false,如果這不是我想要的行爲,並且我更喜歡每次都創建新的views/viewmodels。然後至少前者從RegionManager中刪除。 如果我不想擦除它們並仍然希望這種舊的內存消耗行爲,我仍然可以實現INavigationAware並在IsNavigationTarget中返回false。通過這種方式,RegionManager每次都會創建新的實例,並且仍然保留對舊實例的引用。 另一種方式我不能阻止他創建新的實例註冊名稱不等於類型名稱。在這種情況下甚至沒有達到IsNavigationTarget,這告訴我RegionManager根本不查找現存的視圖。那麼爲什麼我們在這裏有兩種不同的行爲,取決於我註冊我的導航視圖的名稱? 我是否錯誤當我認爲當兩個名稱相同時應用的行爲應該是唯一的行爲,因爲所有其他方案仍然可以使用提到的附加屬性創建?

史蒂夫

回答

1

您註冊在容器中的一些名稱的視圖(模型)。然後可以根據註冊名稱創建視圖(模型)的實例。這允許RequestNavigate創建視圖(模型)並根據註冊名稱激活它。

但是,當RequestNavigate正在檢查目標視圖的可能存在實例(並可能請求IsNavigationTarget)的區域時,它必須處理該區域中視圖(模型)的實例。他們的註冊名稱不可用 - 只有容器知道他們。因此,RequestNavigate假定註冊名稱是視圖類型的Name或FullName。

因此,如果你想擁有所有的功能,你應該在他們的類型名稱下注冊視圖(模型)。有一個方便的方法來做到這一點 - RegisterTypeForNavigation。