zoukankan      html  css  js  c++  java
  • Silverlight中的导航总结

    导航经常在程序中要用到,Silverlight中的导航分为两大类,三小类.

     两大类:使用导航框架来完成(Frame,或者NavigationService类(包含在Page类中)),或者使用传统的修改容器的Content或者是Child等内容来实现导航

    下面慢慢来讲解:

    一.通过非框架的方式来完成

      1.其实这种方式的原理很简单,就是修改容器的根元素,比如我们的页面元素如下

        <Grid x:Name="LayoutRoot">

    </Grid>

    没错,就是只有一个Grid,我们可以通过修改Grid的Children来实现导航,代码如下:

                LayoutRoot.Children.Clear();
    LayoutRoot.Children.Add(
    new Page());

    Children是Grid的所有子元素的集合,类型是UIElement,所以我们实例化一个Page(或者是UserControl)来实现导航,切忌,在导航前调用Grid.Children.Clear()方法,这样才能

    保证我们导航到的页面正确.

    2.如果你觉得这种方式太繁琐,ok,我们可以来使用另一种相似的方法来实现,同样是使用Grid,只不过我们这次Grid的位置变了,Grid不在某个页面,而是在App.cs中.没错,我们要定义一个Grid的对象,在App中,如下所示,我们修改App.RootVisual为自定义的Grid,然后通过Grid.Children.Add(Page)来实现页面的跳转,之所以使用这个是,是因为我们可以在任何一个页面访问App的元素,所以我们想修改Grid的Children也非常方便,当我们修改了Grid的Children,页面的RootVisual当然也就修改了.如下:

    复制代码
            public Grid rootGrid = new Grid();
    private void Application_Startup(object sender, StartupEventArgs e)
    {
    UserControl startPage = new UsingContentLoader();
    this.RootVisual = rootGrid;
    rootGrid.Children.Add(startPage);
    }
    复制代码

    在一个页面中通过App.rootGird来跳转页面,如下,在按钮事件中得到当前的App,然后操作rootGrid对象,即可完成跳转:

         private void btnNavigation_Click(object sender, RoutedEventArgs e)
    {
    App app
    = (App)App.Current;
    app.rootGrid.Children.Clear();
    app.rootGrid.Children.Add(
    new MainPage());
    }

    二.通过框架来完成导航

       使用框架的导航我们同样有两个选择,一个是使用Frame来完成导航,而另一个是使用Page的内置类NavigationService来完成,其实本质没有太大区别

      1.使用Frame

       JournalOwnership属性:默认情况下,仅当无法找到包含自己的日记的父导航宿主 (NavigationWindowFrame) 时,Frame 才会使用自己的导航历史记录(例如,如果承载 Frame 的内容由 Window 承载)。 若要强制 Frame 管理自己的导航历史记录,请将 JournalOwnership 设置为 OwnsJournal

       Frame严格来说是一个控件,主要目的就是用来导航,通常和Button和HyperLink结合来使用,写法如下:

       这个是最简单的Frame的写法,仅仅指定了Name(在后台使用Frame的Navigation可以来导航)和Source(默认显示的页面,当然也可以在托管代码来改变,实现导航)

     <sdk:Frame Name="MainFrame" Source="/Navigation/Pages/CustomCachedPage.xaml" />

      通常我们的Frame不止这么简单,还需要指定UriMapping,也就是导航映射,没错,我们指定了导航映射,可以简化我们的导航的代码,下面现在App中定义一个导航资源

      在App.xaml中定义一个UriMapper设定一个Key(这样才知道其他Xaml中指定使用的是哪一个UriMapper),同时注意需要指定一个默认的页面,也就是需要给Source

      一个默认值,所以添加一个Uri为空的映射,这样就实现了默认的映射.当然也可以指定传参的Uri,当我们的Uri满足这样的格式,则会跳转到映射的页面,并传递参数,可以通过

    NavigationContext.QueryString.ContainsKey("id")来判断是否包含某一个参数,使用NavigationContext.QueryString["id"]来得到某一个参数

    复制代码
     <Application.Resources>
    <navigation:UriMapper x:Key="PageMapper">
    <!--必须指定初始页面-->
    <navigation:UriMapping Uri="" MappedUri="/MainPage.xaml"></navigation:UriMapping>
    <navigation:UriMapping Uri="BtnFrame" MappedUri="/Navigation/Frames/BtnFrame.xaml"></navigation:UriMapping>
    <navigation:UriMapping Uri="Products/{id}" MappedUri="/Views/ProductPage.xaml?id={id}"></navigation:UriMapping>
    </navigation:UriMapper>
    </Application.Resources>
    复制代码

    在页面中使用UriMapper,没错,使用StaticResoucr 来使用UriMapper,这样当我们在页面中使用Mainfram.Navigation方法的时候就会使用这个映射规则

    <sdk:Frame Name="MainFrame" UriMapper="{StaticResource PageMapper}" />

    调用导航的方法:

      MainFrame.Navigate(new Uri("BtnFrame", UriKind.Relative));

    使用Frame导航传参:

    指定Mapping:

     <uriMapper:UriMapping Uri="/About/{Id}" MappedUri="/Views/About.xaml?productId={Id}"></uriMapper:UriMapping>

    可以看到除了/About之外加了{Id},这个{Id}表示传递一个参数(当然不一定必须是 Url后边的参数,可以把它当做成一个动态的匹配值,在这里仅仅为参数作用).

    接下来开始使用这个传参的Url:

    <HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}" 
    NavigateUri
    ="/About/test" TargetName="ContentFrame" Content="about"/>

    当然也可以在托管代码中使用,在托管代码中可以使用 Frame的Navigate方法来进行导航.

    ContentFrame.Navigate(new Uri("/About?productId=test",UriKind.RelativeOrAbsolute));

    可以看到Uri是没有xaml后缀的,因为配置了这个Mapping,那么在导航的时候会自己去匹配规则的。

    也可以使用NavigationService(该属性仅仅在Page页面中有,在UserControl是没有的)的Navigate方法。

     this.NavigationService.Navigate(new Uri("/Home?Id=12",UriKind.RelativeOrAbsolute));

    参数是传递过去了,但是接收呢,page类有一个属性NavigationContext(导航上下文对象),该对象有一个属性QueryString,是不是很熟悉,没错作用和ASP.NET中的

    Request.QueryString一样,保存了URl中的参数,但是呢为了保证获得参数的顺利,在使用参数之前对参数进行判断是否存在使用NavigationContext.QueryString.ContainsKey("paramname")或者NavigationContext.QueryString.Keys.Contains("paramname")来判断是否存在,或者参数值则直接通过参数名字获取NavigationContext.QueryString["paramname"].ToString()

       if (this.NavigationContext.QueryString.Keys.Contains("productId"))
    HtmlPage.Window.Alert(this.NavigationContext.QueryString["productId"].ToString());

    2.NavigationService的导航(Page类的导航)

      之所以Page类可以实现导航,那是因为Page类中的NavigationService框架,因为它有好多方法来实现导航的功能.

      下面先来看看Page类有哪些用于导航的东西:

      Page的常用属性:

    属性

    类型

    描述

    NavigationCacheMode

    NavigationCacheMode

    该属性用于获取或设置一个值,改制指定当前导航页面是否开启导航缓存;该属性默认值为Disabled(表示不开启导航缓存),EnabledRequired属性值表示开启导航缓存,其不同的是Required不受CacheSize限制,每次导航时都重复利用缓存实例;而Enabled受制于CacheSize缓存尺寸,超过尺寸时则放弃缓存实例

    NavigationContext

    NavigationContext

    获取当前导航请求中的对象信息,该属性常被用于获取URI查询字符串值,实现导航框架传值

    NavigationService

    NavigationService

    获取当前导航框架导航服务实例,通过该属性可以获取当前页面导航请求,该属性将在后文详细讲解。

    Title

    String

    该属性用于获取或设置当前导航页面的名称

    Page类的方法:

    方法

    描述

    OnFragmentNavigation

    该方法在导航到页面上的片段时被调用

    OnNavigatedFrom

    该方法在当前页面不再为导航框架中的活动页面时被调用

    OnNavigatedTo

    该方法在当前页面成为导航框架中的活动页面时被调用

    OnNavigatingFrom

    该方法在当前页面不再为导航框架中的活动页面前被调用

    刚才提到了Page中很重要的一个属性就是NavigationService,因为他可以作为一个导航框架,那是因为他有很多导航的方法如下:

    方法

    描述

    GoBack

    该方法用于导航当前页面后退到历史记录中上一页,如果后退导航时没有历史记录页面,则返回异常

    GoForward

    该方法用于导航当前页面前进到历史记录中下一页,如果前进导航时没有历史记录页面,则返回异常

    Navigate

    该方法用于导航到指定URI页面,该URI可以是导航映射相对地址,也可以是导航页面绝对地址

    Refresh

    该方法用于重载当前导航页,该方法经常被用于自定义INavigationContentLoader

    StopLoading

    该方法用于停止所有导航异步进程,该方法常被用于停止正在下载载入的导航页面

    NavigationService类提供以下常用属性和事件:

    事件

    描述

    FragmentNavigation

    该事件在导航到内容片段时被激活

    Navigated

    该事件在导航完成时被激活

    Navigating

    该事件在导航开始时被激活

    NavigationFailed

    该事件在导航抛出异常失败时被激活

    NavigationStopped

    该事件在StopLoading方法被调用时,或者取消当前导航请求时被激活

     

    使用NavigationService来导航,其实非常简单,仅仅一行代码实现了页面的跳转:

    this.NavigationService.Navigate(new Uri(“/Home.xaml”, UriKind.Relative));

     对于NavigationService类而言,值得注意的是该类包含两个特殊的方法,分别是Refresh()和StopLoading(), 这两个方法主要针对当前页面进行操作

    Refresh方法,功能类似浏览器的刷新按钮,该方法将重载当前Page类页面,实现页面刷新效果,如果页面允许支持缓存,将从缓存中读取当前页面。
    StopLoading方法,功能类似浏览器的停止按钮,该方法将停止正在运行的页面载入进程或者其他异步进程,在实际项目中,该方法并不常用。

     

    Page类的NavigationContext属性

    该属性包含两个常用的属性,即Uri和QueryString,使用NavigationContext.Uri获取当前URI路径字符串,使用NavigationContext.QueryString来获得页面之间的

    传值,在本文的前边已经有例子.

    string uriText = String.Format(“/User.xaml?userID={0}&role={1}”, userID, userRole);
    mainFrame.Navigate(
    new Uri(uriText), UriKind.Relative);

    使用NavigattionContext.QueryString来获得

    int userID, userRole;
    if (this.NavigationContext.QueryString.ContainsKey(“userID”))
    userID
    = Int32.Parse(this.NavigationContext.QueryString[“userID”]);
    if (this.NavigationContext.QueryString.ContainsKey(“userRole”))
    userRole
    = Int32.Parse(this.NavigationContext.QueryString[“userRole”]);

     Page类的NavigationCacheMode属性

    Page类的NavigationCacheMode属性是Silverlight导航框架重要属性之一,其功能可以保存导航页面状态。 NavigationCacheMode属性中包含有三个枚举成员,分别是Disabled,Required和Enabled,其含义分别是:
     

    NavigationCacheMode.Disabled: 不支持缓存页面,每次导航应用访问时创建 一个新的页面实例;
    NavigationCacheMode.Required: 支持缓存页面,并且每次导航应用访问时都重复利用该缓存实例,而且忽略Frame类中CacheSize属性设置大小;
    NavigationCacheMode.Enabled: 支持缓存页面,如果超过Frame类中CacheSize属性设置尺寸,则放弃保存缓存实例;

     

    默认情况下,NavigationCacheMode为Disabled状态,也就是说,在Silverlight导航框架应用时,不记录任何信息到缓存。当NavigationCacheMode状态设置为Required后,每当用户结束一次导航操作,Frame类将保存页面对象到内存,当用户点击返回或者前进时,将重新载入保存的缓存状态到当前Page类页面,而当前Page类页面的构造函数不再执行,但是其Loaded事件将被激活。当 NavigationCacheMode为Enabled状态时,则会参考Frame类中CacheSize属性设置尺寸设置。例如:如果设置Frame 类CacheSize属性值为6,当第七个Page类页面载入时,第一个载入到缓存的Page类 页面将会从缓存中删除,而最新的Page类页面将会替代。

  • 相关阅读:
    Mvc+三层(批量添加、删除、修改)
    js中判断复选款是否选中
    EF的优缺点
    Git tricks: Unstaging files
    Using Git Submodules
    English Learning
    wix xslt for adding node
    The breakpoint will not currently be hit. No symbols have been loaded for this document."
    Use XSLT in wix
    mfc110ud.dll not found
  • 原文地址:https://www.cnblogs.com/jason_zhou/p/2545031.html
Copyright © 2011-2022 走看看