1. 程式人生 > >從PRISM開始學WPF(八)導航Navigation-更新至Prism7.1

從PRISM開始學WPF(八)導航Navigation-更新至Prism7.1

log person 返回值 icon new 一個 content per www

原文:從PRISM開始學WPF(八)導航Navigation-更新至Prism7.1

0x6Navigation

[7.1updated] Navigation 在wpf中並沒有變化

Basic Navigation

Prism中的Navigation提供了一種類似導航的功能,他可以根據用戶的輸入,來刷新UI。

先看一個最簡單的例子,通過按鈕來導航到一個視圖,在這裏,視圖被註冊為Navication。
7.1中不再使用構造函數註入依賴,而是新增了兩個接口OnInitialized和RegisterTypes,前面region的應用的時候,我們使用的是OnInitialized,導航這他用了RegisterTypes,代碼如下,將view註冊成Navication,並且註冊到容器中:

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<ViewA>();
            containerRegistry.RegisterForNavigation<ViewB>();
        }

Shell 視圖中設置兩個Button並且綁定下面這個帶參數的命令:

        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);
        }
    <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>

RegionManager通過RequestNavigate方法來獲取已經註冊的Navigation並且綁定到Region上去。

當需要根據調用結果來處理一些事情,可以使用下面這個方法:

void RequestNavigate(string regionName, string source, Action<NavigationResult> navigationCallback);

當然,上面這個方法是在Shell中調用的,但,有些時候,我們需要View或者ViewModel也參與到Navigation中來,比如當你Request一個Navigation的時候,希望navigation本身顯示一些信息,為此 Prism為我們提供了一個INavigationAware 接口。

    //
    // Summary:
    //     Provides a way for objects involved in navigation to be notified of navigation
    //     activities.
    public interface INavigationAware
    {
        //
        // Summary:
        //     Called to determine if this instance can handle the navigation request.
        //
        // Parameters:
        //   navigationContext:
        //     The navigation context.
        //
        // Returns:
        //     true if this instance accepts the navigation request; otherwise, false.
        bool IsNavigationTarget(NavigationContext navigationContext);
        //
        // Summary:
        //     Called when the implementer is being navigated away from.
        //
        // Parameters:
        //   navigationContext:
        //     The navigation context.
        void OnNavigatedFrom(NavigationContext navigationContext);
        //
        // Summary:
        //     Called when the implementer has been navigated to.
        //
        // Parameters:
        //   navigationContext:
        //     The navigation context.
        void OnNavigatedTo(NavigationContext navigationContext);
    }

如果想要Navigation的目標也參與到Navigation的過程當中,只需要讓你的viewmodel實現這個接口,然後在這些方法裏編寫你的代碼就可以了。
IsNavigationTarget方法設置了是否被允許設置為導航的目標,當他的返回值為Fasle的時候,將不會被“導航”到它。

19-NavigationParticipation的例子中,Region的目標是:

        <TabControl prism:RegionManager.RegionName="ContentRegion" Margin="5"  />

TabControl在設置為Region的時候,加載View時會自動創建Page來存放View,如果“導航”到同一個View他會在Page中找到他,並且顯示出來。但如果IsNavigationTarget返回False的話,就不會顯示之前的Page而是創建了一個新的Page來加載View。

PassingParameters帶參數的導航

使用Navigation的時候,將數據源帶到新的NavigationTarget中去,然後Target應用這些數據。這將使用到navigation的NavigationContext參數:

        private void PersonSelected(Person person)
        {
            var parameters = new NavigationParameters();
            parameters.Add("person", person);

            if (person != null)
                _regionManager.RequestNavigate("PersonDetailsRegion", "PersonDetail", parameters);
        }

在Target的OnNavigatedTo方法中使用:


        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            var person = navigationContext.Parameters["person"] as Person;
            if (person != null)
                SelectedPerson = person;
        }

當導航變更的時候你需要一些提示框,需要實現IConfirmNavigationRequest
他有一個ConfirmNavigationRequest方法來進行一些判斷。

在上面的例子中,我們在view之間跳轉的時候,viewA 和viewB是被緩存的,但是有時候,我們跳轉到B的時候想要銷毀A,怎麽來做呢?
在View或ViewModel上實現IRegionMemberLifetime接口,並將KeepAlive屬性的值設置為false。

journal

journal 實現一種類似瀏覽器前進後退按鈕一樣的效果,當一個region 有多個view的時候,他會自動記錄view的加載順序,然後在view之間來回切換。
Prism中是通過IRegionNavigationJournal來實現的,在視圖加載時,講道理,可以無限級前進和後退的,我自己在官方的例子上加了一個視圖也完美運行。

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            _journal = navigationContext.NavigationService.Journal;
        }

然後使用 :

_journal.GoBack();

或者

_journal.GoForward();

從PRISM開始學WPF(八)導航Navigation-更新至Prism7.1