(本文档是WPF的帮助文档,但大部分内容也适用于WP7)
导航服务
虽然 Hyperlink 允许用户发起转向特定 Page 的导航,但是定位和下载该页的工作仍由 NavigationService 类执行。NavigationService 实现了更高级别的支持。
.CurrentSource 存储所导航的上一页的 pack URI。
利用导航服务的编程导航
Hyperlink 就能够找到和使用导航宿主的导航服务来处理导航请求。
NavigationService,这些情况包括:
-
Page 页。
-
Page 之前设置其属性。
-
Page 只能在运行时确定。
NavigationService 的引用。
获取对 NavigationService 的引用
NavigationService。
...
// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = NavigationService.GetNavigationService(this);
下面的示例对此进行演示。
...
// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = this.NavigationService;
对页对象的编程导航
Page。
x:Class="SDKSample.PageWithNonDefaultConstructor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PageWithNonDefaultConstructor">
<!-- Content goes here -->
</Page>
namespace SDKSample
{
public partial class PageWithNonDefaultConstructor : Page
{
public PageWithNonDefaultConstructor(string message)
{
InitializeComponent();
this.Content = message;
}
}
}
Page。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NSNavigationPage">
<Hyperlink Click="hyperlink_Click">
Navigate to Page with Non-Default Constructor
</Hyperlink>
</Page>
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService
namespace SDKSample
{
public partial class NSNavigationPage : Page
{
public NSNavigationPage()
{
InitializeComponent();
}
void hyperlink_Click(object sender, RoutedEventArgs e)
{
// Instantiate the page to navigate to
PageWithNonDefaultConstructor page = new PageWithNonDefaultConstructor("Hello!");
// Navigate to the page, using the NavigationService
this.NavigationService.Navigate(page);
}
}
}
利用 Pack URI 的编程导航
下面的示例对此进行演示。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NSUriNavigationPage">
<Hyperlink Click="hyperlink_Click">Navigate to Page by Pack URI</Hyperlink>
</Page>
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService
namespace SDKSample
{
public partial class NSUriNavigationPage : Page
{
public NSUriNavigationPage()
{
InitializeComponent();
}
void hyperlink_Click(object sender, RoutedEventArgs e)
{
// Create a pack URI
Uri uri = new Uri("AnotherPage.xaml", UriKind.Relative);
// Get the navigation service that was used to
// navigate to this page, and navigate to
// AnotherPage.xaml
this.NavigationService.Navigate(uri);
}
}
}
刷新当前页
.Refresh 方法,如下例所示。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NSRefreshNavigationPage">
<Hyperlink Click="hyperlink_Click">Refresh this page</Hyperlink>
</Page>
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService
namespace SDKSample
{
public partial class NSRefreshNavigationPage : Page
{
...
void hyperlink_Click(object sender, RoutedEventArgs e)
{
// Force WPF to download this page again
this.NavigationService.Refresh();
}
}
}
导航生存期
NavigationService 实现的下列事件来跟踪和影响导航:
-
可用于取消导航。
-
在下载过程中定期发生,以提供导航进度信息。
-
在已定位和下载页后发生。
-
StopLoading)时发生,或者在当前导航进行过程中请求新的导航时发生。
-
在导航到所请求内容出错时发生。
-
在导航到的页已加载、分析并已开始呈现时发生。
-
在开始导航到内容片段时发生,具体情况为:
-
如果所需片段在当前内容中,则立即发生。
-
如果所需片段在其他内容中,则在加载源内容之后发生。
-
导航事件的引发顺序如下图所示。
NavigationWindow 提供相同的事件,以检测二者各自范围内的导航。
下面的示例对此进行演示。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.CancelNavigationPage">
<Button Click="button_Click">Navigate to Another Page</Button>
</Page>
using System.Windows; // RoutedEventArgs, MessageBox, MessageBoxResult
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService, NavigatingCancelEventArgs
namespace SDKSample
{
public partial class CancelNavigationPage : Page
{
public CancelNavigationPage()
{
InitializeComponent();
// Can only access the NavigationService when the page has been loaded
this.Loaded += new RoutedEventHandler(CancelNavigationPage_Loaded);
this.Unloaded += new RoutedEventHandler(CancelNavigationPage_Unloaded);
}
void button_Click(object sender, RoutedEventArgs e)
{
// Force WPF to download this page again
this.NavigationService.Navigate(new Uri("AnotherPage.xaml", UriKind.Relative));
}
void CancelNavigationPage_Loaded(object sender, RoutedEventArgs e)
{
this.NavigationService.Navigating += new NavigatingCancelEventHandler(NavigationService_Navigating);
}
void CancelNavigationPage_Unloaded(object sender, RoutedEventArgs e)
{
this.NavigationService.Navigating -= new NavigatingCancelEventHandler(NavigationService_Navigating);
}
void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
// Does the user really want to navigate to another page?
MessageBoxResult result;
result = MessageBox.Show("Do you want to leave this page?", "Navigation Request", MessageBoxButton.YesNo);
// If the user doesn't want to navigate away, cancel the navigation
if (result == MessageBoxResult.No) e.Cancel = true;
}
}
}
Page 导航来说,可能会产生副作用。
利用日记记住导航
JournalEntry 类的实例,称为“日记条目”。
页生存期和日记
如果日记“记忆”导航过的页,则此类 XBAP 可能很快就会明显消耗大量内存。
Page 都有如下图所示的生存期。
KeepAlive。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.KeepAlivePage"
KeepAlive="True">
An instance of this page is stored in the journal.
</Page>
Unloaded 事件。
Page 不处于活动状态,不应执行以下任何操作:
-
存储对该页或其任何部分的引用。
-
不是由该页实现的事件注册事件处理程序。
Page 保留在内存中的引用,即使该页从日记中移除后,它仍保留在内存中。
不过,这涉及到将在下一节中讨论的状态问题。
利用导航历史记录保留内容状态
Page 的新实例,所以收集数据的控件将重新实例化,从而丢失数据。
Page 导航到其他位置时是如何使用此支持的:
-
Page 的条目添加到日记中。
-
Page 的状态随该页的日记条目存储,该日记条目添加到后退堆栈中。
-
Page。
Page 时,将执行以下步骤:
-
Page(后退堆栈的顶级日记条目)实例化。
-
Page 的日记条目一起存储的状态。
-
Page。
Page 上使用了以下控件,WPF 会自动使用此支持:
ListBox 所示。
DependencyProperty)。
IProvideCustomContentState 接口,可以减少代码量。
.AddBackEntry。
结构化导航
Page。
结构化导航概述。