开发学院WEB开发ASP.NET WPF学习笔记3. Navigation 阅读

WPF学习笔记3. Navigation

 2010-10-11 16:02:19 来源:WEB开发网   
核心提示:互联网的兴起,造就和培养了一种新的用户交互界面 —— Page & Navigation,WPF学习笔记3. Navigation,无论是前进、后退还是页面,都完全是一个全新的门类,当多个页面存在循环链接时,会导致多个页面实例被日志记录,不同于以往的 SDI/MDI,WPF 或者是它的简化版 S

互联网的兴起,造就和培养了一种新的用户交互界面 —— Page & Navigation。无论是前进、后退还是页面,都完全是一个全新的门类,不同于以往的 SDI/MDI。WPF 或者是它的简化版 Silverlight 都不可避免地遵从了这种改良的 B/S 模式,使用 URI 来串接 UI 流程。

NavigationService、Page、Hyperlink、Journal(日志/历史记录) 是 WPF 整个导航体系的核心。NavigationService 提供了类似 IE Host 的控制环境,Journal 可以记录和恢复相关 Page 的状态,我们通常会选用的宿主方式包括:Browser(XBAP) 和 NavigationWindow。

1. NavigationWindow

NavigationWindow 继承自 Window,不知什么原因,我并没有在 VS2008 "New Item..." 中找到相关的条目,只好自己动手将一个 Window 改成 NavigationWindow。

Window1.xaml

<NavigationWindow x:Class="Window1"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="Window1" Height="300" Width="300" WindowStartupLocation="CenterScreen"
 Source="Page1.xaml">
</NavigationWindow>

Source 属性指定了该窗口的默认页面,当然,我们还要修改一下 Window1.xaml.cs 里的基类。

public partial class Window1 : NavigationWindow

{
 public Window1()
 {
  InitializeComponent();
 }
}

创建一个 Page1.xaml,我们就可以像普通 Window 那样添加相关的控件和操作。

2. Hyperlink

超链接应该是我们最熟悉的一种导航方式。

Page1.xaml

<Page x:Class="Learn.WPF.Page1"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="Page1">
 <Grid>
  <TextBlock>
   <Hyperlink NavigateUri="Page2.xaml">Page2</Hyperlink>
  </TextBlock>
 </Grid>
</Page>

NavigateUri 相当于 "Html a.href",当然我们也可以使用 Hyperlink.Click 事件,然后使用 NavigationService 来完成导航操作。

Page1.xaml

<Hyperlink Click="Hyperlink_Click">Page2</Hyperlink>

Page1.xaml.csprivate void Hyperlink_Click(object sender, RoutedEventArgs e)
{
 this.NavigationService.Navigate(new Uri("Page2.xaml", UriKind.Relative));
}

Hyperlink 还支持 "test.htm#name" 这样的导航定位方式,滚动页面直到某个特定名称的控件被显示。Hyperlink 的另外一个实用属性是 Command,我们可以使用 NavigationCommands 中创建的一系列静态成员来执行一些常用操作。

<Hyperlink Command="NavigationCommands.Refresh">Refresh</Hyperlink>
<Hyperlink Command="NavigationCommands.BrowseBack">BrowseBack</Hyperlink>
<Hyperlink Command="NavigationCommands.BrowseForward">BrowseForward</Hyperlink>

3. NavigationService

很多时候我们都需要使用 NavigationService 代替 Hyperlink.NavigateUri,比如非默认构造的 Page,动态确定目标页面等等。我们可以使用 Page.NavigationService 或者 NavigationService.GetNavigationService() 获得 NavigationService 的实例引用 (别忘了添加 using System.Windows.Navigation)。

public partial class Page1 : Page
{
 private void Hyperlink_Click(object sender, RoutedEventArgs e)
 {
  var page2 = new Page2();
  page2.label1.Content = "Beijing 2008!";
  this.NavigationService.Navigate(page2);
 }
}

除了 Navigate(),还可以使用 NavigationService 的两个属性完成导航切换操作。

//this.NavigationService.Content = page2;

this.NavigationService.Source = new Uri("Page2.xaml", UriKind.Relative);

NavigationService 提供了大量的方法和时间来管理相关导航操作。

日志: AddBackEntry、RemoveBackEntry。

载入: Navigate、Refresh、StopLoading。

切换: GoBack、GoForward。

事件: Navigating(新导航请求时触发,可取消导航)……

我们也可以使用 Application 的相关事件来处理导航过程。

4. Journal

Journal 相当于 WebBrowser.History,它包含两个数据栈用来记录前进和后退页面的显示状态,每个相关 Page 都会对应一个 JournalEntry。日志状态自动恢复仅对单击导航条上前进后退按钮有效。

5. Page

有关 Page 本身的使用并不是本文的内容,我们此处关心的是它在导航过程中的生命周期。在 WPF 中,Page 注定是个短命鬼,无论我们使用导航还是后退按钮都会重新创建 Page 对象实例,然后可能是日志对其恢复显示状态。也就是说日志只是记录了 Page 相关控件的状态数据,而不是 Page 对象引用(默认情况下)。

有两种方式来维持一个 Page 引用。第一种就是我们自己维持一个 Page 引用,比如使用某个类似 Application.Properties 这样的容器。

private void Hyperlink_Click(object sender, RoutedEventArgs e)
{
 var page2 = Application.Current.Properties["page2"] as Page2;
 if (page2 == null)
 {
  page2 = new Page2();
  page2.label1.Content = DateTime.Now.ToString();
  Application.Current.Properties["page2"] = page2;
 }
 this.NavigationService.Navigate(page2);
 //this.NavigationService.Content = page2;
}

另外一种就是设置 Page.KeepAlive 属性,这样一来日志会记录该 Page 的引用,当我们使用前进后退按钮时,将不会再次创建该 Page 的对象实例。

<Page x:Class="Learn.WPF.Page2"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="Page2" Loaded="Page_Loaded"
 KeepAlive="True">
</page>
 

有一点需要注意:该方法仅对前进后退等日志操作有效。如果我们使用 HyperLink.NavigateUri 或 NavigationService.Navigate() 导航时依旧会生成新的页面实例,并可能代替日志中最后一个同类型的对象引用记录。另外,当多个页面存在循环链接时,会导致多个页面实例被日志记录,造成一定的内存浪费。

1 2  下一页

Tags:WPF 学习 笔记

编辑录入:爽爽 [复制链接] [打 印]
[]
  • 好
  • 好的评价 如果觉得好,就请您
      0%(0)
  • 差
  • 差的评价 如果觉得差,就请您
      0%(0)
更多精彩
    赞助商链接

    热点阅读
      焦点图片
        最新推荐
          精彩阅读