========================================================= 本文为转载,转载必须确保本文完整并完整保留原作者信息和本文链接 E-mail: khler@163.com QQ: 23381103 MSN: pragmac@hotmail.com 原文:http://www.rainsts.net/article.asp?id=737 =========================================================
互联网的兴起,造就和培养了一种新的用户交互界面 —— Page & Navigation。无论是前进、后退还是页面,都完全是一个全新的门类,不同于以往的 SDI/MDI。WPF 或者是它的简化版 Silverlight 都不可避免地遵从了这种改良的 B/S 模式,使用 URI 来串接 UI 流程。
<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.cs
private 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() 导航时依旧会生成新的页面实例,并可能代替日志中最后一个同类型的对象引用记录。另外,当多个页面存在循环链接时,会导致多个页面实例被日志记录,造成一定的内存浪费。 6. Frame Frame 的作用和 HTML 中的 IFrame 类似,我们可以用它在一个普通的 Window 或 Page 中嵌套显示其他的 Page。
<Window x:Class="Learn.WPF.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"> <Grid> <Frame Source="Page1.xaml"></Frame> </Grid> </Window> 默认情况下,Frame 会尝试使用上层页面(Page)或窗体(NavigationWindow)的日志,当然我们也可以使用 JournalOwnership 属性强行让 Frame 使用自己的日志导航。
<Frame Source="Page1.xaml" JournalOwnership="OwnsJournal"></Frame>
Frame 的另外一个作用就是可以导航到 HTML 页面,我们可以把它当作一个嵌入式 IE WebBrowser 来使用。
<Frame Source="http://www.rainsts.net" />
7. PageFunction<T> WPF 提供了一个称之为 PageFunction 的 Page 继承类来实现类似 HTML showModal 的功能。我们可以用它来收集某些数据并返回给调用页,当然这个封装其实非常简单,我们完全可以自己实现,无非是提供一个类似 OnReturn 的方法实现而已。泛型参数 T 表示返回数据类型。 Page1.xaml.cs
public partial class Page1 : Page
{ private void Hyperlink_Click(object sender, RoutedEventArgs e) { var modal = new PageFunction1(); modal.Return += (s, ex) => this.label1.Content = ex.Result.ToString(); this.NavigationService.Navigate(modal); } } PageFunction1.xaml.cs
public partial class PageFunction1 : PageFunction<int>
{ private void button1_Click(object sender, RoutedEventArgs e) { OnReturn(new ReturnEventArgs<int>(DateTime.Now.Millisecond)); } }
|
WPF 学习: Navigation
最新推荐文章于 2024-07-18 15:24:29 发布
WPF 学习: Navigation
2010年09月16日 星期四 上午 11:45