WPF应用程序可以实现类似Web浏览器的导航方式,以切换不同的页面。WPF提供两种导航方式:独立应用程序和 XAML 浏览器应用程序 (XBAP)。大概思路是:Page类作为导航的页面,用来展示不同界面呈现。Hyperlink或NavigationService对象实现从一个Page页面导航到另一个Page页面,而导航的路线则由日志来记录,便于回退导航过程。
所以,Page、Hyperlink、NavigationService和日志组成了WPF页面导航的核心内容。
一、Page页面
首先我们要熟悉Page页面,实际上,它也是一个控件。下面是它的定义:
public class Page : FrameworkElement, IWindowService, IAddChild
{
public static readonly DependencyProperty ContentProperty;
public static readonly DependencyProperty BackgroundProperty;
public static readonly DependencyProperty TitleProperty;
public static readonly DependencyProperty KeepAliveProperty;
public static readonly DependencyProperty ForegroundProperty;
public static readonly DependencyProperty FontFamilyProperty;
public static readonly DependencyProperty FontSizeProperty;
public static readonly DependencyProperty TemplateProperty;
public Page();
public double WindowWidth { get; set; }
public Brush Background { get; set; }
public string Title { get; set; }
public bool ShowsNavigationUI { get; set; }
public FontFamily FontFamily { get; set; }
public NavigationService NavigationService { get; }
public Brush Foreground { get; set; }
public double WindowHeight { get; set; }
public bool KeepAlive { get; set; }
public string WindowTitle { get; set; }
public ControlTemplate Template { get; set; }
public double FontSize { get; set; }
public object Content { get; set; }
protected internal override IEnumerator LogicalChildren { get; }
public bool ShouldSerializeShowsNavigationUI();
public bool ShouldSerializeTitle();
public bool ShouldSerializeWindowHeight();
public bool ShouldSerializeWindowTitle();
public bool ShouldSerializeWindowWidth();
protected override Size ArrangeOverride(Size arrangeBounds);
protected override Size MeasureOverride(Size constraint);
protected virtual void OnTemplateChanged(ControlTemplate oldTemplate, ControlTemplate newTemplate);
protected internal sealed override void OnVisualParentChanged(DependencyObject oldParent);
}
从定义上看,Page页面继承于FrameworkElement基类,它拥有下面这些属性。
属性 | 说明 |
WindowWidth | 获取或设置窗体的宽度,Page本身是一个控件,需要一个窗体来承载,窗体通常是Window或者NavigationWindow。 |
Background | 获取或设置页面背景 |
Title | 获取或设置页面标题 |
ShowsNavigationUI | 是否显示导航UI |
FontFamily | 获取或设置指定的字体系列的名称。 |
NavigationService | 获取Page页的宿主使用来管理导航的导航服务。 |
Foreground | 获取或设置Page前景 |
WindowHeight | 获取或设置窗体的高度、 |
KeepAlive | 获取或设置是否在导航历史记录中保留Page实例 |
WindowTitle | 获取或设置窗体的标题 |
Template | 获取或设置页面的控件模板 |
FontSize | 获取或设置字体大小。 |
Content | 获取或设置页面的内容 |
从它的Content属性来看,Page和ContentControl内容控件很相似,页面的内容直接赋值到Content属性上即可。
二、创建第一个Page页面
Page页面的创建和窗体、用户控件一样,在“项目”右键菜单中选择“添加”-“页面(WPF)”,输入页面的类名,即可完成一个页面的创建。
然后,我们简单地设置一下Page,以及在Page中添加一些内容。比如,我们将Page页面的窗体宽高设置为550和350,标题也适当修改一下。
<Page x:Class="HelloWorld.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HelloWorld"
mc:Ignorable="d"
WindowWidth="550"
WindowHeight="350"
WindowTitle="WPF中文网:wpfsoft.com - Page示例"
Title="Page1">
<Grid>
<TextBlock Text="Page1"
FontSize="60"
Foreground="DarkCyan"/>
</Grid>
</Page>
需要注意的是,如何启动第一个页面?这里需要修改App.xaml代码,将StartupUri的内容修改为页面的名称:Page1.xaml
<Application x:Class="HelloWorld.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:HelloWorld"
StartupUri="Page1.xaml">
<Application.Resources>
</Application.Resources>
</Application>
然后启动这个项目,如下图所示,就可以看到第一个页面的内容了。
为了能顺序的加载Page页面,WPF会自动为这个页面实例化一个NavigationWindow,它表示支持内容导航的窗体。我们可以通过可视化树找到它的踪迹。
从上图中可以清楚地看到Page1的外层就是NavigationWindow。NavigationWindow 派生自 Window ,并通过导航到和显示内容的功能对其进行扩展。内容可以是任何.NET Framework对象或 HTML 文件。 但是,通常, Page 对象是打包内容以用于导航的首选方法。
下一节,我们来介绍这个NavigationWindow,以及如果在两个Page页面之间实现导航。
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:110-《页面和导航的概述》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff
——重庆教主 2023年11月23日