zoukankan      html  css  js  c++  java
  • 从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();
    
  • 相关阅读:
    [LeetCode 1029] Two City Scheduling
    POJ 2342 Anniversary party (树形DP入门)
    Nowcoder 106 C.Professional Manager(统计并查集的个数)
    2018 GDCPC 省赛总结
    CF 977 F. Consecutive Subsequence
    Uva 12325 Zombie's Treasure Chest (贪心,分类讨论)
    Poj 2337 Catenyms(有向图DFS求欧拉通路)
    POJ 1236 Network of Schools (强连通分量缩点求度数)
    POJ 1144 Network (求割点)
    POJ 3310 Caterpillar(图的度的判定)
  • 原文地址:https://www.cnblogs.com/hicolin/p/8742693.html
Copyright © 2011-2022 走看看