註冊導航頁面
註冊區域
使用p:RegionManager.RegionName註冊頁面區域
<Window x:Class="WpfApp1.NavigationWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:p="http://prismlibrary.com/" Title="NavigationWindow" Width="800" Height="450" mc:Ignorable="d"> <DockPanel> <Grid Width="220" DockPanel.Dock="Left"> <StackPanel> <Button Margin="0,3" Command="{Binding OpenViewCommand}" CommandParameter="ViewA" Content="View A" /> <Button Margin="0,3" Command="{Binding OpenViewCommand}" CommandParameter="ViewB" Content="View B" /> <Button Margin="0,3" Content="View C" /> </StackPanel> </Grid> <Grid> <!--<ContentControl p:RegionManager.RegionName="ViewRegion"/>--> <TabControl p:RegionManager.RegionName="ViewRegion"> <TabControl.ItemContainerStyle> <Style TargetType="TabItem"> <!-- TabItem的繫結資料來源是頁面物件 --> <!-- TabItem的DataContext=View物件 --> <!-- View物件的DataContext=對應的ViewModel --> <Setter Property="Header" Value="{Binding DataContext.Title}" /> </Style> </TabControl.ItemContainerStyle> </TabControl> </Grid> </DockPanel> </Window>
public class NavigationWindowVewModel { public ICommand OpenViewCommand { get; set; } // 區域管理,需要拿到RegionManager IRegionManager _regionManager; public NavigationWindowVewModel(IRegionManager regionManager) { _regionManager = regionManager; OpenViewCommand = new DelegateCommand<string>(DoOpenView); } private void DoOpenView(string viewName) { _regionManager.RegisterViewWithRegion("ViewRegion", viewName); } }
public class Startup : PrismBootstrapper { protected override DependencyObject CreateShell() { return Container.Resolve<NavigationWindow>(); //return Container.Resolve<MainWindow>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterForNavigation<ViewA>(); containerRegistry.RegisterForNavigation<ViewB>(); } protected override void ConfigureViewModelLocator() { base.ConfigureViewModelLocator(); ViewModelLocationProvider.Register(typeof(NavigationWindow).ToString(), typeof(NavigationWindowVewModel)); } }
<UserControl x:Class="WpfApp1.Views.ViewA" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> <StackPanel> <TextBox FontSize="20" Foreground="Orange" Text="View A" /> <TextBlock FontSize="20" Foreground="Red" Text="{Binding Title}" /> <Button Command="{Binding CloseTabCommand}" Content="Close" /> </StackPanel> </UserControl>
<UserControl x:Class="WpfApp1.Views.ViewB" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> <Grid> <TextBlock FontSize="20" Foreground="Green" Text="View B" /> </Grid> </UserControl>
public class ViewAViewModel { public string Title { get; set; } = "View A"; public ICommand CloseTabCommand { get; set; } IRegionManager _regionManager; public ViewAViewModel(IRegionManager regionManager) { _regionManager = regionManager; CloseTabCommand = new DelegateCommand(DoCloseTab); } private void DoCloseTab() { } }
public class ViewBViewModel { public string Title { get; set; } = "View B"; public ICommand CloseTabCommand { get; set; } IRegionManager _regionManager; public ViewBViewModel(IRegionManager regionManager) { _regionManager = regionManager; CloseTabCommand = new DelegateCommand(DoCloseTab); } private void DoCloseTab() { } }
導航頁面傳參——INavigationAware介面
public class ViewAViewModel : INavigationAware { public string Title { get; set; } = "View A"; public ICommand CloseTabCommand { get; set; } IRegionManager _regionManager; public ViewAViewModel(IRegionManager regionManager) { _regionManager = regionManager; CloseTabCommand = new DelegateCommand(DoCloseTab); } private void DoCloseTab() { } #region INavigationAware介面方法 public bool IsNavigationTarget(NavigationContext navigationContext) { // 是否允許重複導航進來 // 主-》A-》B-》A (顯示前物件) 返回True // 主-》A-》B-》A(新物件) 返回false return true; // 編輯頁面,透過主頁的子項點選,開啟這個頁面, // 子項有很多,可能同時開啟多個子項進行編輯 } public void OnNavigatedFrom(NavigationContext navigationContext) { // 從當前View導航出去的時候觸發 // 從某個頁面跳轉到另一個頁面的時候,可以把這個資訊帶過去 navigationContext.Parameters.Add("abcd", "Hello ViewA"); } public void OnNavigatedTo(NavigationContext navigationContext) { // 開啟當前View的時候觸發 string arg = navigationContext.Parameters.GetValue<string>("abcd"); } #endregion }
public class NavigationWindowVewModel { public ICommand OpenViewCommand { get; set; } // 區域管理,需要拿到RegionManager IRegionManager _regionManager; public NavigationWindowVewModel(IRegionManager regionManager) { _regionManager = regionManager; OpenViewCommand = new DelegateCommand<string>(DoOpenView); } private void DoOpenView(string viewName) { //_regionManager.RegisterViewWithRegion("ViewRegion", viewName); // 向某個View中傳遞特定引數,引數對接到View的ViewModel裡 if (viewName == "ViewA") { NavigationParameters parameters = new NavigationParameters(); parameters.Add("abcd", "Hello"); _regionManager.RequestNavigate("ViewRegion", viewName, parameters); } else if (viewName == "ViewB") _regionManager.RequestNavigate("ViewRegion", viewName); } }
自動銷燬——IRegionMemberLifetime介面
頁面的ViewModel繼承IRegionMemberLifetime介面
介面中的KeepAlive引數預設為true:非啟用狀態,在Region中保留
public class ViewAViewModel : INavigationAware , IRegionMemberLifetime { public string Title { get; set; } = "View A"; public ICommand CloseTabCommand { get; set; } IRegionManager _regionManager; public ViewAViewModel(IRegionManager regionManager) { _regionManager = regionManager; CloseTabCommand = new DelegateCommand(DoCloseTab); } public bool KeepAlive => false; private void DoCloseTab() { } #region INavigationAware介面方法 public bool IsNavigationTarget(NavigationContext navigationContext) { // 是否允許重複導航進來 // 主-》A-》B-》A (顯示前物件) 返回True // 主-》A-》B-》A(新物件) 返回false return true; // 編輯頁面,透過主頁的子項點選,開啟這個頁面, // 子項有很多,可能同時開啟多個子項進行編輯 } public void OnNavigatedFrom(NavigationContext navigationContext) { // 從當前View導航出去的時候觸發 // 從某個頁面跳轉到另一個頁面的時候,可以把這個資訊帶過去 navigationContext.Parameters.Add("abcd", "Hello ViewA"); } public void OnNavigatedTo(NavigationContext navigationContext) { // 開啟當前View的時候觸發 string arg = navigationContext.Parameters.GetValue<string>("abcd"); } #endregion }
頁面離開前的事件——IConfirmNavigationRequest介面
頁面ViewModel實現IConfirmNavigationRequest介面
public class ViewAViewModel : INavigationAware,IRegionMemberLifetime,IConfirmNavigationRequest { public string Title { get; set; } = "View A"; public ICommand CloseTabCommand { get; set; } IRegionManager _regionManager; public ViewAViewModel(IRegionManager regionManager) { _regionManager = regionManager; CloseTabCommand = new DelegateCommand(DoCloseTab); } private void DoCloseTab() { } #region IRegionMemberLifetime介面方法 // 用來控制當前頁面非啟用狀態,是否在Region中保留 public bool KeepAlive => true; #endregion #region INavigationAware介面方法 #region INavigationAware介面方法 public bool IsNavigationTarget(NavigationContext navigationContext) { // 是否允許重複導航進來 // 主-》A-》B-》A (顯示前物件) 返回True // 主-》A-》B-》A(新物件) 返回false return true; // 編輯頁面,透過主頁的子項點選,開啟這個頁面, // 子項有很多,可能同時開啟多個子項進行編輯 } public void OnNavigatedFrom(NavigationContext navigationContext) { // 從當前View導航出去的時候觸發 // 從某個頁面跳轉到另一個頁面的時候,可以把這個資訊帶過去 navigationContext.Parameters.Add("abcd", "Hello ViewA"); } public void OnNavigatedTo(NavigationContext navigationContext) { // 開啟當前View的時候觸發 string arg = navigationContext.Parameters.GetValue<string>("abcd"); } #endregion #region IConfirmNavigationRequest介面方法 // 當從當前頁面跳轉到另一個頁面時觸發 // OnNavigatedFrom呼叫前執行 public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback) { // 開啟某個頁面, if (MessageBox.Show("是否離開當前頁面?", "導航提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes) { /// 繼續開啟 /// continuationCallback?.Invoke(true); } else // 不被導航 continuationCallback?.Invoke(false); } #endregion }
導航日誌
編寫測試程式
public class Startup : PrismBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<PrismRegion.Journal.Views.MainView>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewA>();
containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewB>();
containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewC>();
}
}
public partial class App : Application
{
public App()
{
new Startup().Run();
}
}
<Window x:Class="Zhaoxi.PrismRegion.Journal.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Zhaoxi.PrismRegion.Journal.Views"
xmlns:p="http://prismlibrary.com/"
mc:Ignorable="d"
Title="MainView" Height="450" Width="800">
<Grid>
<Button Content="Load Views" Command="{Binding BtnLoadCommand}"
VerticalAlignment="Top"/>
<ContentControl p:RegionManager.RegionName="MainRegion" Margin="0,30,0,0"/>
</Grid>
</Window>
public class MainViewModel
{
public DelegateCommand BtnLoadCommand { get; set; }
public MainViewModel(IRegionManager regionManager)
{
BtnLoadCommand = new DelegateCommand(() =>
{
regionManager.RequestNavigate("MainRegion", "ViewA");
});
}
}
<UserControl x:Class="Zhaoxi.PrismRegion.Journal.Views.ViewA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Zhaoxi.PrismRegion.Journal.Views"
mc:Ignorable="d" FontSize="20"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<StackPanel>
<TextBlock Text="View A" Foreground="Orange" />
<Button Content="向後" Command="{Binding GoBackCommand}"/>
<Button Content="向前" Command="{Binding ForwordCommand}"/>
</StackPanel>
</Grid>
</UserControl>
頁面的ViewModel繼承INavigationAware介面
在OnNavigatedTo方法中取出navigationContext.NavigationService.Journal
journal.GoBack()提供導航回退
public class ViewAViewModel : INavigationAware
{
public DelegateCommand GoBackCommand { get; set; }
public DelegateCommand ForwordCommand { get; set; }
IRegionNavigationJournal journal;
public ViewAViewModel(IRegionManager regionManager)
{
GoBackCommand = new DelegateCommand(() =>
{
if (journal.CanGoBack)
{
journal.GoBack();
}
});
ForwordCommand = new DelegateCommand(() =>
{
if (journal.CanGoForward)
{
journal.GoForward();
}
else
{
regionManager.RequestNavigate("MainRegion", "ViewB");
}
});
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
journal = navigationContext.NavigationService.Journal;
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
}
}
參照ViewA寫ViewB和ViewC
修改對應ViewModel的GoBackCommand與ForwordCommand
public ViewBViewModel(IRegionManager regionManager)
{
GoBackCommand = new DelegateCommand(() =>
{
if (journal.CanGoBack)
{
journal.GoBack();
}
});
ForwordCommand = new DelegateCommand(() =>
{
if (journal.CanGoForward)
{
journal.GoForward();
}
else
{
regionManager.RequestNavigate("MainRegion", "ViewC");
}
});
}
public ViewCViewModel(IRegionManager regionManager)
{
GoBackCommand = new DelegateCommand(() =>
{
if (journal.CanGoBack)
{
journal.GoBack();
}
});
ForwordCommand = new DelegateCommand(() =>
{
if (journal.CanGoForward)
{
journal.GoForward();
}
});
}
執行後實現導航的前進後退
取消導航——IJournalAware
在ViewB的ViewModel中繼承IJournalAware介面,並在實現方法中返回false。
public class ViewBViewModel : INavigationAware, IJournalAware
{
public DelegateCommand GoBackCommand { get; set; }
public DelegateCommand ForwordCommand { get; set; }
IRegionNavigationJournal journal;
public ViewBViewModel(IRegionManager regionManager)
{
GoBackCommand = new DelegateCommand(() =>
{
if (journal.CanGoBack)
{
journal.GoBack();
}
});
ForwordCommand = new DelegateCommand(() =>
{
if (journal.CanGoForward)
{
journal.GoForward();
}
else
{
regionManager.RequestNavigate("MainRegion", "ViewC");
}
});
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
journal = navigationContext.NavigationService.Journal;
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
}
// IJournalAware的方法實現
public bool PersistInHistory()
{
return false;
}
}
執行後,導航會取消ViewB的導航
來源:https://www.cnblogs.com/ZHIZRL/p/17883434.html