Prism区域异常问题分析(导航失效?)
前文
本篇文章主要討論在WPF當(dāng)中使用Prism區(qū)域?qū)Ш降氖У膯栴}, 在其它的博客當(dāng)中也出現(xiàn)了多次討論這個(gè)問題以及對應(yīng)的解決方法,
例如重寫OnInitialized方法等等。我認(rèn)為這都不是解決問題的根源, 既然如此, 下面我們將來分析Prism的IRegionManager的具體流程。
Prism初始化過程
首先, 我們分析一下下面的代碼, 用于創(chuàng)建應(yīng)用程序的主頁
protected override Window CreateShell(){return Container.Resolve<MainWindow>();}那么, 在這個(gè)MainWindow當(dāng)中, 如果我們定于以下一個(gè)區(qū)域, 則可以使用IRegionManager進(jìn)行導(dǎo)航操作, 如下所示:
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ShowRegion" />現(xiàn)在問題就來了, 一旦我們把這個(gè)窗口的實(shí)例銷毀, 自己重新創(chuàng)建一個(gè)MainWindow的時(shí)候, 你會發(fā)現(xiàn)你無法進(jìn)行導(dǎo)航了, 這個(gè)時(shí)候就是大家理解的那個(gè)問題, 是Region失效了?
并不是, 為了解決這個(gè)問題, 我們需要了解Prism框架本身做了什么動作, 查看源代碼之后, 發(fā)現(xiàn)以下初始化代碼:
了解到, 從一開始獲取到MainWindow之后, 陸續(xù)進(jìn)行了上下文綁定, 設(shè)置IRegionManager實(shí)例以及更新區(qū)域的操作。
在這里, 我們至少了解了幾個(gè)東西。
MainWindow的DataContext初始化的時(shí)機(jī)
MainWindow窗口當(dāng)中IRegionManager的初始化過程
區(qū)域刷新的動作
完成了這些動作之后, 最終ShowDialog展示了首頁, 于是,我們可以在這里愉快的使用IRegionManager進(jìn)行導(dǎo)航操作。
分析結(jié)果
如果想要實(shí)現(xiàn)在某個(gè)窗口當(dāng)中進(jìn)行導(dǎo)航, 除了定義區(qū)域之外, 你還需要做的就是給窗口設(shè)置IRegionManager的實(shí)例以及刷新區(qū)域, 核心就是這兩行代碼:
RegionManager.SetRegionManager(shell, _containerExtension.Resolve<IRegionManager>());RegionManager.UpdateRegions();既然我們了解到這個(gè)之后, 還有一個(gè)問題也順其自然的解決了, 在Prism當(dāng)中使用彈窗服務(wù)不能導(dǎo)航的問題, 因?yàn)樵赑rism框架提供的IDialogService中并沒有實(shí)現(xiàn)
設(shè)置IRegionManager以及刷新區(qū)域, 這就是問題的根源, 所以我們必須手動的去修改實(shí)現(xiàn)達(dá)到支持導(dǎo)航的功能。
彈窗中實(shí)現(xiàn)導(dǎo)航
示例: 以下代碼, 展示了如何在彈窗當(dāng)中設(shè)置區(qū)域以及刷新區(qū)域的問題。
var provider = ContainerLocator.Container.Resolve<IContainerProvider>();var regionManager = ContainerLocator.Container.Resolve<IRegionManager>();var win = provider.Resolve<object>("ShowWindow");if (win is Window view){RegionManager.SetRegionManager(view, regionManager);RegionManager.UpdateRegions();view.ShowDialog();}當(dāng)然, 你完全可以自行實(shí)現(xiàn)IDialogService接口覆蓋Prism提供的內(nèi)部實(shí)現(xiàn), 以達(dá)到彈窗支持導(dǎo)航的行為, 例如:
public interface IMyDialogService : IDialogService{}public class MyDialogService : DialogService, IMyDialogService{public MyDialogService(IContainerExtension containerExtension): base(containerExtension){}public new void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback){//...}}總結(jié)
對于任何窗口, 我們都可以使用IRegionManager進(jìn)行導(dǎo)航操作, 在第一次框架初始化的時(shí)候, 只不過是Prism內(nèi)部幫我們處理了區(qū)域的設(shè)置以及刷新行為。
而如何我們想在其它地方使用區(qū)域?qū)Ш? 則需要手動設(shè)置區(qū)域以及刷新區(qū)域即可。
總結(jié)
以上是生活随笔為你收集整理的Prism区域异常问题分析(导航失效?)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET6之MiniAPI(七):中间件
- 下一篇: 华为云服务器初探二(完结)