新建檢視UserControl
及其ViewModel,被跳轉的檢視的VM需要實現INavigationAware
在App.xaml.cs
中註冊檢視及其ViewModel
// App.xaml.cs
containerRegistry.RegisterForNavigation<IndexView, IndexViewModel>();
ContentControl
及region
佔位: <DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="5" >
<Button Command="{Binding NavigateCommand}" CommandParameter="ViewA" Margin="5">Navigate to View A</Button>
<Button Command="{Binding NavigateCommand}" CommandParameter="ViewB" Margin="5">Navigate to View B</Button>
</StackPanel>
<ContentControl prism:RegionManager.RegionName
="{x:Static ext:PrismManager.MainViewRegionName}" />
</DockPanel>
Region
是Prism
內部的一個資料結構,它的Name
屬性是此處在XAML中宣告的RegionName
(詳見下節)。// ViewModel
public DelegateCommand<string> NavigateCommand { get; private set; }
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
}
private void Navigate(string navigatePath)
{
if (navigatePath != null)
_regionManager.RequestNavigate("ContentRegion", navigatePath);
}
Region
對應的是在XAML中宣告的 ContentControl
的附加屬性 prism:RegionManager.RegionName
RegionManager
管理著所有 Region
物件,這些 Region
物件被裝到 RegionCollection
中的列表屬性
RegionManager
中的3個方法
UpdateRegions
在 PrismApplicationBase#Initialize
中被呼叫,它會根據在XAML中宣告的RegionName
建立 Region
物件RequestNavigate
在需要導航時呼叫,呼叫它時會根據 regionName 去 regionCollection 中找到對應的 Region
物件,並通過集合 ActiveViews
找到滿足條件的 View 範例從而進行 ContentControl
內容的切換RegisterViewWithRegion
進行 Region
和檢視的註冊由於 View 和 ViewModel 的初始化 MvvmHelpers.AutowireViewModel(shell);
先於 Region
的初始化RegionManager.UpdateRegions();
,因此在View和ViewModel初始化時找不到相應的 Region
物件。
// PrismApplicationBase.cs
protected virtual void Initialize()
{
// ...
if (shell != null)
{
MvvmHelpers.AutowireViewModel(shell);
RegionManager.SetRegionManager(shell, _containerExtension.Resolve<IRegionManager>());
RegionManager.UpdateRegions();
InitializeShell(shell);
}
// ...
在視窗初始化時,Initilized
事件發生時資料繫結未完成;Loaded
事件發生時資料繫結已經完成。
因此,可以手動註冊 Region
;也可以在資料繫結結束之後存取 Region
。
方法1 Loaded事件
private void Window_Loaded(object sender, RoutedEventArgs e)
{
regionManager.RequestNavigate("ContentRegion", "ViewA");
}
方法2 手動註冊 Region
// App.xaml.cs
protected override void Initialize()
{
base.Initialize();
var regionManager = Container.Resolve<IRegionManager>();
regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
}
// ViewModel
public MainWindowViewModel(IRegionManager regionManager)
{
regionManager.RequestNavigate("ContentRegion", "ViewA");
}
方法3 Dispatcher
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
{
regionManager.RequestNavigate("ContentRegion", "ViewA");
}));