Prism(八) 导航 源码地址 - WineMonk/PrismStudy: Prism框架学习 (github.com)
导航基础 视图 ViewA/B.xaml
1 2 3 4 5 6 7 8 9 10 <UserControl x:Class="ModuleA.Views.ViewA" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"> <StackPanel> <TextBlock Text="{Binding Title}" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" /> <TextBlock Text="{Binding PageViews}" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> </UserControl>
ViewA/BViewModel.cs
1 2 3 4 5 6 7 public class ViewAViewModel : BindableBase { public ViewAViewModel () { } }
注册导航视图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class ModuleAModule : IModule { public void OnInitialized (IContainerProvider containerProvider ) { } public void RegisterTypes (IContainerRegistry containerRegistry ) { containerRegistry.RegisterForNavigation<ViewA>(); containerRegistry.RegisterForNavigation<ViewB>(); } } public partial class App : PrismApplication { protected override Window CreateShell () { return Container.Resolve<MainWindow>(); } protected override void RegisterTypes (IContainerRegistry containerRegistry ) { } protected override void ConfigureModuleCatalog (IModuleCatalog moduleCatalog ) { moduleCatalog.AddModule<ModuleA.ModuleAModule>(); } }
导航视图 MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <Window x:Class="BasicRegionNavigation.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" Title="{Binding Title}" Height="350" Width="525"> <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="ContentRegion" Margin="5" /> </DockPanel> </Window>
MainWindowViewModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class MainWindowViewModel : BindableBase { private readonly IRegionManager _regionManager; private string _title = "Prism Unity Application" ; public string Title { get { return _title; } set { SetProperty(ref _title, value ); } } 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); } }
导航视图请求回调 MainWindowViewModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class MainWindowViewModel : BindableBase { private readonly IRegionManager _regionManager; private string _title = "Prism Unity Application" ; public string Title { get { return _title; } set { SetProperty(ref _title, value ); } } 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, NavigationComplete); } private void NavigationComplete (NavigationResult result ) { System.Windows.MessageBox.Show(String.Format("Navigation to {0} complete. " , result.Context.Uri)); } }
视图察觉参与导航 ViewA/B.xaml
1 2 3 4 5 6 7 8 9 10 <UserControl x:Class="ModuleA.Views.ViewA" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"> <StackPanel> <TextBlock Text="{Binding Title}" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" /> <TextBlock Text="{Binding PageViews}" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> </UserControl>
ViewA/BViewModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class ViewAViewModel : BindableBase , INavigationAware { private string _title = "ViewA" ; public string Title { get { return _title; } set { SetProperty(ref _title, value ); } } private int _pageViews; public int PageViews { get { return _pageViews; } set { SetProperty(ref _pageViews, value ); } } public ViewAViewModel () { } public void OnNavigatedTo (NavigationContext navigationContext ) { PageViews++; } public bool IsNavigationTarget (NavigationContext navigationContext ) { return true ; } public void OnNavigatedFrom (NavigationContext navigationContext ) { } }
通过参数导航 Model Person.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 public class Person : INotifyPropertyChanged { #region Properties private string _firstName; public string FirstName { get { return _firstName; } set { _firstName = value ; OnPropertyChanged(); } } private string _lastName; public string LastName { get { return _lastName; } set { _lastName = value ; OnPropertyChanged(); } } private int _age; public int Age { get { return _age; } set { _age = value ; OnPropertyChanged(); } } private DateTime? _lastUpdated; public DateTime? LastUpdated { get { return _lastUpdated; } set { _lastUpdated = value ; OnPropertyChanged(); } } #endregion //Properties #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged ([CallerMemberName]string propertyname = null ) { PropertyChanged?.Invoke(this , new PropertyChangedEventArgs(propertyname)); } #endregion //INotifyPropertyChanged public override string ToString () { return String.Format("{0}, {1}" , LastName, FirstName); } }
View PersonList.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <UserControl x:Class="ModuleA.Views.PersonList" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"> <UserControl.Resources> <Style TargetType="TabItem"> <Setter Property="Header" Value="{Binding DataContext.SelectedPerson.FirstName}" /> </Style> </UserControl.Resources> <Grid x:Name="LayoutRoot" Margin="10" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="100" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ListBox x:Name="_listOfPeople" ItemsSource="{Binding People}"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <prism:InvokeCommandAction Command="{Binding PersonSelectedCommand}" CommandParameter="{Binding SelectedItem, ElementName=_listOfPeople}" /> </i:EventTrigger> </i:Interaction.Triggers> </ListBox> <TabControl Grid.Row="1" Margin="10" prism:RegionManager.RegionName="PersonDetailsRegion" /> </Grid> </UserControl>
PersonDetail.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <UserControl x:Class="ModuleA.Views.PersonDetail" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- First Name --> <TextBlock Text="First Name:" Margin="5" /> <TextBlock Grid.Column="1" Margin="5" Text="{Binding SelectedPerson.FirstName}" /> <!-- Last Name --> <TextBlock Grid.Row="1" Text="Last Name:" Margin="5" /> <TextBlock Grid.Row="1" Grid.Column="1" Margin="5" Text="{Binding SelectedPerson.LastName}" /> <!-- Age --> <TextBlock Grid.Row="2" Text="Age:" Margin="5"/> <TextBlock Grid.Row="2" Grid.Column="1" Margin="5" Text="{Binding SelectedPerson.Age}"/> </Grid> </UserControl>
ViewModel PersonListViewModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 using System;using ModuleA.Business;using Prism.Mvvm;using Prism.Navigation.Regions;namespace ModuleA.ViewModels { public class PersonDetailViewModel : BindableBase , INavigationAware { private Person _selectedPerson; public Person SelectedPerson { get { return _selectedPerson; } set { SetProperty(ref _selectedPerson, value ); } } public PersonDetailViewModel () { } public void OnNavigatedTo (NavigationContext navigationContext ) { var person = navigationContext.Parameters["person" ] as Person; if (person != null ) SelectedPerson = person; } public bool IsNavigationTarget (NavigationContext navigationContext ) { var person = navigationContext.Parameters["person" ] as Person; if (person != null ) return SelectedPerson != null && SelectedPerson.LastName == person.LastName; else return true ; } public void OnNavigatedFrom (NavigationContext navigationContext ) { } } }
PersonDetailViewModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 using ModuleA.Business;using Prism.Commands;using Prism.Mvvm;using Prism.Navigation.Regions;using System;using System.Collections.ObjectModel;namespace ModuleA.ViewModels { public class PersonListViewModel : BindableBase { IRegionManager _regionManager; private ObservableCollection<Person> _people; public ObservableCollection<Person> People { get { return _people; } set { SetProperty(ref _people, value ); } } public DelegateCommand<Person> PersonSelectedCommand { get ; private set ; } public PersonListViewModel (IRegionManager regionManager ) { _regionManager = regionManager; PersonSelectedCommand = new DelegateCommand<Person>(PersonSelected); CreatePeople(); } private void PersonSelected (Person person ) { var parameters = new NavigationParameters(); parameters.Add("person" , person); if (person != null ) __regionManager.RequestNavigate("PersonDetailsRegion" , typeof (PersonDetail).Name, parameters); } private void CreatePeople () { var people = new ObservableCollection<Person>(); for (int i = 0 ; i < 10 ; i++) { people.Add(new Person() { FirstName = String.Format("First {0}" , i), LastName = String.Format("Last {0}" , i), Age = i }); } People = people; } } }
导航请求处理 ViewA/BViewModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public class ViewAViewModel : BindableBase , IConfirmNavigationRequest { public ViewAViewModel () { } public void ConfirmNavigationRequest (NavigationContext navigationContext, Action<bool > continuationCallback ) { bool result = true ; if (MessageBox.Show("Do you to navigate?" , "Navigate?" , MessageBoxButton.YesNo) == MessageBoxResult.No) result = false ; continuationCallback(result); } public bool IsNavigationTarget (NavigationContext navigationContext ) { return true ; } public void OnNavigatedFrom (NavigationContext navigationContext ) { } public void OnNavigatedTo (NavigationContext navigationContext ) { } }