WPF的Page介绍及Page Window Frame 之间的链接使用示例,嵌套问题
本文源参考 http://www.cnblogs.com/ListenFly/archive/2013/02/24/2923474.html 谢谢源作者
WPF中的Page相比Window来说更加的精简,因为他没有提供一个Show或者是Hide的方法,而是通过链接的方式进行页面切换。此外, 一般来说Page不设置自身的大小,因为页面的尺寸由包含它的宿主窗体来决定的。如果设置了页面的Width和Height大小,如果宿主的大小小于页面 的,则页面会被裁剪;如果宿主的大小大于页面的,则页面会居中显示。同时页面可以设置WindowWidth和WindowHeight以及 WindowTitle来设置宿主的宽度、高度、标题属性。
先看个例子:
NavigationWindow win = new NavigationWindow();
//未设置大小
//win.Content = new Page1();
//宿主大小大于Page尺寸
//win.Content = new Page1(300,300,500,500);
//宿主大小小于Page尺寸
win.Content = new Page1(500, 500, 300, 300);
win.Show();
例子中设置了三种不同情况下页面和宿主窗体之间的大小关系,看到的三种情况如下
三张图片分别为,未对窗体进行大小设置,宿主大于页面,宿主小于页面.
下面介绍下Page页面的宿主问题:
Page的宿主包括浏览器,导航窗口(NavigationWindow)和Frame,上例子中已经使用了NavigationWindow。 后两种均为WPF提供的Page宿主窗口,提供了从一个Page导航到另一个Page的功能,同时可以记录历史导航,以及一系列的导航事件。其中 NavigationWindow继承自Window,所以在外观上与普通的窗口最大的区别是多了一个导航工具栏,不过可以通过设置 ShowsNavigationUI属性控制是否显示。
NavigationWindow为顶级窗口,不允许嵌入到其他的元素中。而 Frame则为轻量级,可以嵌入到其他元素中,如NavigationWindow或者Page,甚至Frame的嵌套。Frame默认没有导航栏,可以 设置NavigationUIVisibility属性为Visible使其显示。
例子,如下例子在NavigationWindow中放置了一个Page,然后在Page中嵌套了一个Frame:
<Page x:Class="WpfApplication4.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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Page1">
<Border BorderBrush="Red" BorderThickness="2" Margin="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="该页面的宿主窗口是一个NavigationWindow"
HorizontalAlignment="Center" VerticalAlignment="Center" ></TextBlock>
<Frame Source="Page2.xaml" NavigationUIVisibility="Visible" Grid.Row="1"></Frame>
</Grid>
</Border>
</Page>
同时设置App中的StartUrl为Page,效果如下:
可以看到,最外层是拥有导航的NavigationWindow,而内层还嵌套一个拥有导航的Frame.
细心的童鞋会发现,在上例子中我们并没有添加NavigationWindow的代码,可为什么还是有了效果呢?这是因为当设置了StartUri的对象为Page而不是Window,WPF就会为该Page创建一个NavigationWindow。
下面开始介绍Page之间的导航链接:
1.超链接(HyperLink)
<Hyperlink Click="Hyperlink_Click_1">开始阅读路由事件</Hyperlink>
<Hyperlink NavigateUri="Page4.xaml">开始阅读路由事件</Hyperlink>
private void Hyperlink_Click_1(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("pack://application:,,,/Page4.xaml"));
}
上述代码使用了HyperLink的两种方式进行导航,一种是设置NavigateUri属性为目标页,另一种是使用NavigationService类的Navigate方法来进行导航页(当然,此方法不限于
HyperLink使用).
除了上述比较简单的使用外,HyperLink还可以在元素之间进行导航,例子如下:
<Page x:Class="WpfApplication4.Page4"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Page4"> <Grid>
<FlowDocumentReader>
<FlowDocument>
<Paragraph x:Name="para" FontSize="24" Background="AliceBlue">
<Figure Width="100" Height="100" HorizontalAnchor="ColumnRight" HorizontalOffset="-10" VerticalAnchor="ParagraphTop" VerticalOffset="-30">
<BlockUIContainer>
<Image Source="bee.png"/>
</BlockUIContainer>
</Figure>
路由事件(Routed Event)
</Paragraph>
<Section FontFamily="华文仿宋"> <Paragraph>
黄蓉凝目看去,只见那两只玉蜂双翅上也都有字,那六个字也是一模一样,右翅是“情谷底”,左翅是“我在绝”。黄蓉大奇,暗想:“造物虽奇,也决造不出这样一批蜜蜂来之理。其中必有缘故。” ……
</Paragraph>
<Paragraph>
黄蓉不答,只是轻轻念着:“情谷底,我在绝。情谷底,我在绝。”她念了几遍,随即省悟:“啊!那是‘我在绝情谷底’。是谁在绝情谷底啊?难道是襄儿?”心中怦怦乱跳……
</Paragraph>
<Paragraph TextAlignment="Right">
——《神雕侠侣:第三十八回 生死茫茫》
</Paragraph>
</Section>
<Section LineHeight="25" FontSize="15">
<Paragraph >
这一段讲的是小龙女深陷绝情谷地,用花树上的细刺,在玉蜂翅上刺下‘我在绝情谷底’六字,盼望玉蜂飞上之后,能为人发现。结果蜂翅上的细字被周伯通发现,而给黄蓉隐约猜到了其中含义。本节内容包括:
</Paragraph>
<List >
<ListItem>
<Paragraph>
<Hyperlink NavigateUri="Page4.xaml#first">
<!--<Hyperlink Click="Hyperlink_Click">-->
从玉蜂说起,回顾.Net事件模型
</Hyperlink>
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
<Hyperlink NavigateUri="Page4.xaml#second">
什么是路由事件?
</Hyperlink>
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
CLR事件足够完美,为什么还需要路由事件?
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
言归正传,话路由事件
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
路由事件的实例
</Paragraph>
</ListItem>
</List>
</Section>
<Paragraph x:Name="first" FontSize="20" Background="AliceBlue">
1. 从玉蜂说起,回顾.Net事件模型
</Paragraph>
<Paragraph>
木木熟悉神雕侠侣的故事,于是他根据“玉蜂传信”这样一个故事,信手画下这样一幅有趣的图。
</Paragraph>
<BlockUIContainer>
<Image Source="routedevent.jpg"/>
</BlockUIContainer>
<Paragraph>
其实这一幅“玉蜂传信图”暗合.Net的事件模型。小龙女是事件的发布者,她发布了事件“我在绝情谷底”;老顽童和黄蓉是事件的订阅者,不过老顽童并没有处理该事件,而黄蓉处理了事件,隐约能猜出其中含义;至于可怜的小杨过,则根本没有订阅事件,只是苦苦念叨“龙儿,龙儿,你在哪儿……”;而玉蜂正是传递信息的事件。事件,事件的发布者和事件的订阅者构成了.Net事件模型的三个角色。在.Net当中,一个事件是用关键字event来表示的。如下代码所示:
</Paragraph>
<Paragraph xml:space="preserve" Background="#88888888">
public delegate void WhiteBee(string param); //声明了玉蜂的委托
// 小龙女类
class XiaoLongnv
{
public event WhiteBee WhiteBeeEvent; //玉蜂事件
public void OnFlyBee()
{
Console.WriteLine("小龙女在谷底日复一日地放着玉蜂,希望杨过有一天能看到.....");
WhiteBeeEvent(msg);
}
private string msg = "我在绝情谷底";
} // 老顽童类
class LaoWantong
{
public void ProcessBeeLetter(string msg)
{
Console.WriteLine("老顽童:小蜜蜂、小蜜蜂,别跑");
}
} // 黄蓉类
class Huangrong
{
public void ProcessBeeLetter(string msg)
{
Console.WriteLine("黄蓉:\"{0}\",莫非......",msg);
}
} // 杨过类
class YangGuo
{
public void ProcessBeeLetter(string msg)
{
Console.WriteLine("杨过:\"{0}\",我一定会找她!", msg);
}
public void Sign()
{
Console.WriteLine("杨过叹息:龙儿,你在哪儿....");
}
}
static void Main(string[] args)
{
// 第一步 人物介绍
XiaoLongnv longnv = new XiaoLongnv(); //小龙女
LaoWantong wantong = new LaoWantong(); //老顽童
Huangrong rong = new Huangrong(); //黄蓉
YangGuo guo = new YangGuo(); //杨过 // 第二步 订阅事件,唯独没有订阅杨过的ProcessBeeLetter;
longnv.WhiteBeeEvent += wantong.ProcessBeeLetter;
longnv.WhiteBeeEvent += rong.ProcessBeeLetter;
// longnv.WhiteBeeEvent += guo.ProcessBeeLetter; //杨过是没有订阅小龙女的玉蜂事件 // 第三步 小龙女玉蜂传信
longnv.OnFlyBee(); // 第四步 杨过叹息
guo.Sign();
}
</Paragraph>
<Paragraph x:Name="second" FontSize="20" Background="AliceBlue">
2. 什么是路由事件?
</Paragraph>
<Paragraph>
什么是路由事件呢?木木很快查看了一下MSDN,MSDN从功能和实现两种视角给出了路由事件的定义。
</Paragraph>
<Paragraph>
Functional definition: A routed event is a type of event that can invoke handlers on multiple listeners in an element tree, rather than just on the object that raised the event.
</Paragraph>
<Paragraph>
Implementation definition: A routed event is a CLR event that is backed by an instance of the RoutedEvent class and is processed by the Windows Presentation Foundation (WPF) event system.
</Paragraph>
<Paragraph>
虽然木木现在英语功底已经进步了很多,但是这两个定义还是让他看得一头雾水。看来必须得找个例子有点感性的认识(以大家都非常熟悉的Button的Click事件为例,该事件是个路由事件,可以通过Reflector查看ButtonBase的源码)。
</Paragraph>
</FlowDocument>
</FlowDocumentReader>
</Grid>
</Page>
</ListItem>
<ListItem>
<Paragraph>
路由事件的实例
</Paragraph>
</ListItem>
</List>
</Section>
<Paragraph x:Name="first" FontSize="20" Background="AliceBlue">
1. 从玉蜂说起,回顾.Net事件模型
</Paragraph>
<Paragraph>
木木熟悉神雕侠侣的故事,于是他根据“玉蜂传信”这样一个故事,信手画下这样一幅有趣的图。
</Paragraph>
<BlockUIContainer>
<Image Source="routedevent.jpg"/>
</BlockUIContainer>
<Paragraph>
其实这一幅“玉蜂传信图”暗合.Net的事件模型。小龙女是事件的发布者,她发布了事件“我在绝情谷底”;老顽童和黄蓉是事件的订阅者,不过老顽童并没有处理该事件,而黄蓉处理了事件,隐约能猜出其中含义;至于可怜的小杨过,则根本没有订阅事件,只是苦苦念叨“龙儿,龙儿,你在哪儿……”;而玉蜂正是传递信息的事件。事件,事件的发布者和事件的订阅者构成了.Net事件模型的三个角色。在.Net当中,一个事件是用关键字event来表示的。如下代码所示:
</Paragraph>
<Paragraph xml:space="preserve" Background="#88888888">
public delegate void WhiteBee(string param); //声明了玉蜂的委托
// 小龙女类
class XiaoLongnv
{
public event WhiteBee WhiteBeeEvent; //玉蜂事件
public void OnFlyBee()
{
Console.WriteLine("小龙女在谷底日复一日地放着玉蜂,希望杨过有一天能看到.....");
WhiteBeeEvent(msg);
}
private string msg = "我在绝情谷底";
} // 老顽童类
class LaoWantong
{
public void ProcessBeeLetter(string msg)
{
Console.WriteLine("老顽童:小蜜蜂、小蜜蜂,别跑");
}
} // 黄蓉类
class Huangrong
{
public void ProcessBeeLetter(string msg)
{
Console.WriteLine("黄蓉:\"{0}\",莫非......",msg);
}
} // 杨过类
class YangGuo
{
public void ProcessBeeLetter(string msg)
{
Console.WriteLine("杨过:\"{0}\",我一定会找她!", msg);
}
public void Sign()
{
Console.WriteLine("杨过叹息:龙儿,你在哪儿....");
}
}
static void Main(string[] args)
{
// 第一步 人物介绍
XiaoLongnv longnv = new XiaoLongnv(); //小龙女
LaoWantong wantong = new LaoWantong(); //老顽童
Huangrong rong = new Huangrong(); //黄蓉
YangGuo guo = new YangGuo(); //杨过 // 第二步 订阅事件,唯独没有订阅杨过的ProcessBeeLetter;
longnv.WhiteBeeEvent += wantong.ProcessBeeLetter;
longnv.WhiteBeeEvent += rong.ProcessBeeLetter;
// longnv.WhiteBeeEvent += guo.ProcessBeeLetter; //杨过是没有订阅小龙女的玉蜂事件 // 第三步 小龙女玉蜂传信
longnv.OnFlyBee(); // 第四步 杨过叹息
guo.Sign();
}
</Paragraph>
<Paragraph x:Name="second" FontSize="20" Background="AliceBlue">
2. 什么是路由事件?
</Paragraph>
<Paragraph>
什么是路由事件呢?木木很快查看了一下MSDN,MSDN从功能和实现两种视角给出了路由事件的定义。
</Paragraph>
<Paragraph>
Functional definition: A routed event is a type of event that can invoke handlers on multiple listeners in an element tree, rather than just on the object that raised the event.
</Paragraph>
<Paragraph>
Implementation definition: A routed event is a CLR event that is backed by an instance of the RoutedEvent class and is processed by the Windows Presentation Foundation (WPF) event system.
</Paragraph>
<Paragraph>
虽然木木现在英语功底已经进步了很多,但是这两个定义还是让他看得一头雾水。看来必须得找个例子有点感性的认识(以大家都非常熟悉的Button的Click事件为例,该事件是个路由事件,可以通过Reflector查看ButtonBase的源码)。
</Paragraph>
</FlowDocument>
</FlowDocumentReader>
</Grid>
</Page>
上述代码较长(摘抄自 WPF葵花宝典),使用了一个FlowDocumentReader文本阅读控件,在其中有多个段落(Paragraph),同时在HyperLink中设置了NavigateUri,可以看到
属性值除了包含xaml名称之外,还包含了"#"这样的符号,没错这个就是类似于Html中的,本页之间的超链,通过指定"#元素名称",在点击HyperLink之后,就可以导航到Name
为所指定的元素。
导航工具栏:
上图中的功能是不是很方便呢,这个在WPF中也很容易的实现.
首先,同样的设置一个Page为起始页(WPF会自动添加一个NavigationWindow),然后放置一个按钮按钮用于跳转,点击之后你会神奇的发现,点击导航栏的下拉会显示之前访问的页面和当前页面的链接.
不知道细心的童鞋会思考一个问题,这个链接的文本是怎么得到的呢,问题问的好,这个链接的文本可以来自多个属性,但是最终却是有一个会被使用,优先级如下:
JournalEntry.Name(在Page中设置,一个附加属性)>Page.Title>Page.WindowTitle。
当然,点击工具栏的前进和后退,也可以导航到之前访问的页面去。除了导航栏可以实现前进后退,在其他的按钮中也是可以的,代码如下:
<Button Content="后退" Command="NavigationCommands.BrowseBack"></Button>
<Button Content="前进" Command="NavigationCommands.BrowseForward"></Button>
只需指定按钮的Command属性为对应的命令即可,是不是很简单呢。
WPF的Page介绍及Page Window Frame 之间的链接使用示例,嵌套问题的更多相关文章
- Page Cache与Page回写
综述 Page cache是通过将磁盘中的数据缓存到内存中,从而减少磁盘I/O操作,从而提高性能.此外,还要确保在page cache中的数据更改时能够被同步到磁盘上,后者被称为page回写(page ...
- man page及info page用法
Linux系统的在线求助man page与info page 先来了解一下Linux有多少命令呢?在文本模式下,你可以直接按下两个[Tab]按键,看看总共有多少命令可以让你用? [vbird@www ...
- WPF 3D编程介绍
原文:WPF 3D编程介绍 上一篇文章简单的介绍了WPF编程的相关的内容,也推荐了本书.今天要来讲一下在WPF如何开展3D编程. 使用的xmal 和C#开发的时候:需要使用如下的关键要素: 1:摄像机 ...
- 书籍:wpf学习书籍介绍
WPF参考书推荐 下面先整理下,本人主要学习的WPF参考书: 1.WPF编程宝典(C#2010) 该书:(必读) 心得体会:读完该书后,你对WPF的基础和基本控件的使用,包括WPF的编程模型,相比Wi ...
- ( 转)WPF面板布局介绍Grid、StackPanel、DockPanel、WrapPanel
回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的使用经验,可能还存在错误之处,还请大家指出. 本 ...
- page cache 与 page buffer 转
page cache 与 page buffer 标签: cachebuffer磁盘treelinux脚本 2012-05-07 20:47 2905人阅读 评论(0) 收藏 举报 分类: 内核编程 ...
- Response.Write,Page.RegisterClientScriptBlock和Page.RegisterStartupScript的区别
Response.Write("<script>");输出在文件头部,一打开就执行. RegisterClientScriptBlock一般返回的是客户端函数的包装, ...
- Add custom and listview web part to a page in wiki page using powershell
As we know, Adding list view web part is different from custom web part using powershell, what's mor ...
- man page ,info page 和/usr/share/doc/整理自鸟哥
- 比如查看date指令 - 命令:vbird@www ~]$ man date - 返回示例(部分):DATE(1) User Commands DATE(1) - 部分释义(注释2): ...
随机推荐
- 44. log(n)求a的n次方[power(a,n)]
[题目] 实现函数double Power(double base, int exponent),求base的exponent次方,不需要考虑溢出. [分析] 这是一道看起来很简单的问题,很容易写出如 ...
- 41.把数组排成最小的数[Sort array to smallest value]
[题目] 输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{3,32, 321},则输出这两个能排成的最小数字321323.请给出解决问题的算法,并证明该 ...
- Linux shell脚本编程基础之练习篇
shell脚本编程基础之练习篇. 1.编写一个脚本使我们在写一个脚本时自动生成”#!/bin/bash”这一行和注释信息. #!/bin/bash ] then echo "请输入一个参数& ...
- 六间房 繁星 酷我 来疯 秀吧 新浪秀 直播播放器 Live 1.2
适合用于进行录制的时候 特别说明: 安装 falsh play 19 时 不能正常播放 每个按钮都有提示,不详细说明 下载地址 http://pan.baidu.com/s/1i32ETIt 下载地址 ...
- Java for LeetCode 173 Binary Search Tree Iterator
Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ro ...
- java\c程序的内存分配
JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...
- extjs在窗体中添加搜索框
在extjs中添加搜索框,搜索框代码如下: this.searchField = new Ext.ux.form.SearchField({ store : this.store ...
- 多个list合并
需要多个list合并,如图 @SuppressWarnings("unchecked") @Override public List<CwInfo> get ...
- Codeforces 390A( 模拟题)
Inna and Alarm Clock Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64 ...
- 小吃(codevs 3231)
3231 小吃 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 这里简直是吃货的天堂,小吃太多了. ...