转载自:http://www.cnblogs.com/zlgcool/archive/2008/11/17/1335456.html

WPF面向的是UI展现,而文本显示无疑是UI层中的重要功能之一。WPF提供了XPS (XML 文件规范) 和Flow Document (流文档) 来在不同的场景下展现或者操作文档的显示。XPS(XML 文件规范)针对打印和面向页面的内容,而”流文档”则针对屏幕显示以及提供更动态和可以论证的更复杂模型。“流文档”几乎适用于与文本内容相关的所有方面,从产品说明到整本书籍。

Flow Document是WPF3.0中提供的一个用于显示的新功能,它给了开发人员另一种选择去显示内容。Flow Document通过类似 HTML 文档的格式定义文本流,但其功能更强大,并可提供明显更先进的布局选项。它内置了很多的元素,例如,Figure, Paragraph, Section, Floater, Table, InlineUIContainer等可以通过不同的布局和元素控制其显示方式。并且,它支持对图像的支持,使其可以像在HTML中一样随意控制。再加上其默认支持的导航,显示模式,搜索,让其内容展现方式有了进一步的提高。

Flow Document

Flow Document定义了这个流文档的顶级显示模式,在其内部可以包含诸如Section, Paragraph等标签用来控制其层级显示模式。这就类似于HTML中的DIV,TABLE等区域控制标签一样用来组成文档的显示结构。定义一个流文档很简单,你可以通过声明一个Flow Document和其内部的显示结构即可,例如以下代码通过显示了如何来创建了简单的显示功能。

<Window x:Class="WpfFlowDocuments.Window2"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Example Flow Document Content" Height="300" Width="600" HorizontalAlignment="Stretch">

<Window.Resources>

<Style x:Key="TitleParagraph" TargetType="{x:Type Paragraph}">

<Setter Property="Paragraph.FontFamily" Value="Calibri" />

<Setter Property="Paragraph.FontSize" Value="14pt" />

<Setter Property="Paragraph.Background" Value="Brown" />

<Setter Property="Paragraph.Foreground" Value="White" />

<Setter Property="Paragraph.FontWeight" Value="Bold" />

<Setter Property="Paragraph.TextAlignment" Value="Left" />

</Style>

<Style TargetType="{x:Type Paragraph}">

<Setter Property="Paragraph.FontFamily" Value="Calibri" />

<Setter Property="Paragraph.FontSize" Value="10pt" />

<Setter Property="Paragraph.Foreground" Value="Black" />

</Style>

</Window.Resources>

<FlowDocument>

<Section>

<Paragraph Style="{StaticResource TitleParagraph}">

<Bold>Best Small Businesses to Start</Bold>

</Paragraph>

<Paragraph>

<Underline>Learn from the examples of entrepreneurs who’ve succeeded in these hot start-up areas</Underline>

</Paragraph>

</Section>

<Section>

<Paragraph Background="LightYellow">

By Matthew Bandyk   Posted November 13, 2008

</Paragraph>

</Section>

</FlowDocument>

</Window>

下图显示了XAML的效果。这里仅仅显示了3个Paragraph并以设置了简单的样式,但没有高级布局设置。Flow Document以默认的Page Viewer方式展示。

    

Figure 1: 普通声明的Flow Document以Page Viewer的方式展示

显示模式

Flow Document默认支持三种展现方式,这也对应了上图中右下方的三个按钮。默认的Flow Document会以FlowDocumentReader来生成。对于不同的展现方式,其包含的导航,搜索等都有所不同,甚至缺少某些功能。

·         FlowDocumentPageViewer :以单独的页面显示流文档

·         FlowDocumentScrollViewer:以连续的流显示文档,通过滚动条导航

·         FlowDocumentReader :组合了滚动查看器和页面查看器,让用户可以在两种方法之间切换。这是用于流文档的默认选项。

FlowDocumentPageViewer

此选项以单独的页面显示流文档,让页面翻转而非滚动。这与 Word 中的“阅读版式”类似。以下XAML片段声明了文章以FlowDocumentPageViewer的方式显示。

<FlowDocumentPageViewer BorderThickness="1" BorderBrush="Blue" >

<FlowDocument>

<Section>

<Paragraph Style="{StaticResource TitleParagraph}">

<Bold>Best Small Businesses to Start</Bold>

</Paragraph>

<Paragraph>

<Underline>Learn from the examples of entrepreneurs who’ve succeeded in these hot start-up areas</Underline>

</Paragraph>

</Section>

<Section>

<Paragraph Background="LightYellow">

By Matthew Bandyk   Posted November 13, 2008

</Paragraph>

</Section>

……

</Section>

</FlowDocument>

</FlowDocumentPageViewer>

FlowDocumentPageViewer将提供以翻页的方式来导航内容页。通过你调整窗口的大小,流文档会根据内容的位置、尺寸来调整流的布局(这就是你为什么会在变化窗口大小的时候看到多列的原因,流的布局变化)。

Figure 2: 以FlowDocumentPageViewer方式展现流文档

FlowDocumentPageViewer提供默认的分页导航和ZOOM功能,它提供的Find功能默认为隐藏,可以通过ApplicationCommands.Find命令或Ctrl + F来唤醒Find功能。

FlowDocumentScrollViewer

使用一个滚动条以连续的流显示文档,类似网页或 Microsoft Word 中的”Web 版式”。ScrollViewer模式仅仅是以连续的方式显示流文档的内容,所以其不具备PageViewer的可以自动变化流布局的高级功能。在调整窗口大小时,流文档无法以多页或多列的方式显示。

FlowDocuemntScrollViewer与FlowDocumentPageViewer的用法一模一样,只需要将其关键字替换即可,如:

<FlowDocumentScrollViewerBorderThickness="1" BorderBrush="Blue" >

……

</FlowDocumentScrollViewer>

Figure 3: 以FlowDocuemntScrollViewer方式展现流文档

文档展现视图默认不具有Find栏和ZOOM栏,通过Ctrl + F调用。

FlowDocumentReader

此控件组合了滚动查看器和页面查看器,让用户可以在两种方法之间切换。这是用于流文档的默认控件,而且对于以显示复杂文本为特色的应用程序通常是一个不错的选择。除了将标记用FlowDocumentReader替换前边的两个标记中任何一个,便可以轻松使用这种高级的展现。

<FlowDocumentReaderBorderThickness="1" BorderBrush="Blue" >

……

</ FlowDocumentReader>

注意展现视图中出现了三个展现方式切换的按钮。FlowDocumentReader具有一个名为ViewMode的属性,可取的值为Page, TwoPage和Scroll,通过设置ViewMode可以在设定其初始展现方式。默认为Page,对应于FlowDocumentPageViewer。

Figure 4: 以FlowDocuemnReader方式展现流文档

FlowDocumentReader 控件采取多列的方法呈现文本。这是另一项非常重要的可读性功能,因为人们不喜欢读跨越整个宽屏显示页面宽度的一行行文字。实际列宽因各种因素会有所不同, 例如用于内容显示的可用总宽度、缩放系数和定义的列宽等。流文档的默认列宽为字体大小的 20 倍,默认字体大小约为 300 个与设备无关的像素(3 1/8 英寸的精确尺寸显示)。所以在你调整窗口大小时,一旦窗口宽度可以容纳两个默认列宽,流布局会自动更改为2列显示。但是你可以通过设置ColumnWidth属性来设置你自己的列宽度。

<FlowDocumentReader BorderThickness="1" BorderBrush="Blue">

<!--<FlowDocumentScrollViewer BorderThickness="1" BorderBrush="Blue">-->

<!--<FlowDocumentPageViewer BorderThickness="1" BorderBrush="Blue" >-->

<FlowDocument ColumnWidth="500"> <!-- IsColumnWidthFlexible="False">-->

<Section>

<Paragraph Style="{StaticResource TitleParagraph}">

<Bold>Best Small Businesses to Start</Bold>

</Paragraph>

<Paragraph>

<Underline>Learn from the examples of entrepreneurs who’ve succeeded in these hot start-up areas</Underline>

</Paragraph>

</Section>

…….

</FlowDocument>

</FlowDocumentPageViewer>

默认情况下IsColumnWidthFlexible属性是为true的,这表明在允许范围内(像当前FlowDocument的整体宽度大于ColumnWidth或默认ColumnWidth宽度的整数倍时),将会增大ColumnWidth,这样会让整个布局会更规律和整齐。但你也可以通过设置它为False来强制列宽必须为你指定的宽度,这样在其余的宽度将会保持空白。

通过设置ColumnGap等参数还可以来调整各个列之间的样式。以下代码片段设置了各个列之间的缝隙宽度(ColumnGap)和线条样式。

<FlowDocument ColumnRuleBrush="Gray" ColumnRuleWidth="5" ColumnGap="30">

<Section>

<Paragraph Style="{StaticResource TitleParagraph}">

<Bold>Best Small Businesses to Start</Bold>

</Paragraph>

<Paragraph>

<Underline>Learn from the examples of entrepreneurs who’ve succeeded in these hot start-up areas</Underline>

</Paragraph>

</Section>

………

</FlowDocument>

</FlowDocumentPageViewer>

Figure 5: 通过FlowDocument的属性控制展现

Block嵌套

Flow Document是Block的集合,所有Block都是从 System.Windows.Documents.Block。Block又是从 ContentElement 派生而来,ContentElement 是 WPF 中专门为文档定义优化的一个相当低级别的类。这类似于用来定义 WPF 界面的控件--它们都从 UIElement 派生而来。两者的继承树在概念上很相似,但并不完全相同。这意味着 WPF 控件和块不能直接组合。例如Paragraph中不能直接包含对类似Button的定义,但它可以通过特殊 BlockUIContainer 块类包含任何 WPF 控件。这意味着,流文档可以包含所有类型的 WPF 元素(包括交互式用户界面、媒体和三维元素),而从另一个角度看,流文档也可是任何 WPF 用户界面的一部分,例如可以是控件内容的一个高级布局元素,也可以是一个真正的元素。

展现图像Figure

Figure标记我们通常可以用来展现图像。可以根据设置HorizontalAnchor属性和VerticalAnchor属性的值,流布局会根据其空间布局而改变。这很有助于我们用各种不同的方式来展现图线及其文字的布局。你可以让文字环绕图像,也可以让文字像HTML中的Float一样,这显得很简单。下边的代码片段将图像显示在Content的中央:

<Paragraph>

<Figure Width="120px" HorizontalAnchor="ContentCenter" VerticalAnchor="ContentCenter" BorderBrush="Gray" BorderThickness="1">

<BlockUIContainer>

<Image Source="09.jpg" Height="120px" Width="100px" Margin="0" />

</BlockUIContainer>

<Paragraph Foreground="Blue">

Figure - Model Car</Paragraph>

</Figure>

America's economic future is uncertain. Unemployment is up sharply.
Credit is tight. People are worried about their savings. So is it a
great time to start a business? "Are you crazy?" might be the quick
answer.

</Paragraph>

当然,Figure还有一个重要的用户就是设置标题。对于标题,你可以通过设置Width为1Content或者nColumn等方式来表示其所在布局中的位置。以下代码片段设置了如何定义一个跨越整个文档所有列的标题:

<Paragraph>

<Figure HorizontalAnchor="PageCenter" VerticalAnchor="ContentTop" Width="1Content" Background="Brown">

<Paragraph Foreground="White" FontSize="18">

<Bold>Best Small Businesses to Start</Bold>

</Paragraph>

<Paragraph>

<Italic>Learn from the examples of entrepreneurs who’ve succeeded in these hot start-up areas</Italic>

</Paragraph>

<Paragraph Foreground="Blue">

By Matthew Bandyk

</Paragraph>

<Paragraph Foreground="Blue">

Posted November 13, 2008

</Paragraph>

</Figure>

</Paragraph>

展示一下最终的结果吧。看起来很酷,不是吗?也很容易哦。

Figure 6: 通过Figure标签来定制标题和图像

Float标记

Float标记类似于CSS中的Float属性,它定义了标签内的内容以浮动的方式显示。就像在CSS中的解释一样,它打破当前的流布局,以特定的方式来重新布局内容。HorizontalAlignment 属性和Width属性可以控制其展现方式。

<Paragraph>

The demand for energy efficiency and an environmentally friendly
footprint is also spurring entrepreneurship. Energy auditors help
businesses and homes save money by reducing energy costs.

<Floater HorizontalAlignment="Right" Style="{StaticResource FloatingContent}">

<Paragraph>Retirement Widget</Paragraph>

<Paragraph>Search on Google</Paragraph>

</Floater>

</Paragraph>

Figure 7: Float标签以浮动方式重新布局

InlineUIContainerBlockUIContainer

InlineUIContainer 和 BlockUIContainer 提供了可以在Flow Document中插入WPF控件的能力。InlineUIContainer 可以被声明在像Paragraph等支持inline元素的对象中来Host任意的WPF控件,而BlockUIContainer可以被声明在像Section等支持block元素的对象中。他们都可以host任意的WPF控件。

<Section>

<Paragraph>

This contains some text and

<InlineUIContainer>

<Button>Button Control</Button>

</InlineUIContainer>

interspersed.

</Paragraph>

<Section>

<BlockUIContainer>

<Button>Host In Block Control</Button>

</BlockUIContainer>

</Section>

</Section>

其他标记

类似于Html中我们经常也会用到以下几中元素:

·         Table元素 : 允许内容以表格的方式展现。

<Table BorderBrush="Black" BorderThickness="1">

<Table.Columns>

<TableColumn Width="*"></TableColumn>

<TableColumn Width="2*"></TableColumn>

</Table.Columns>

<TableRowGroup>

<TableRow>

<TableCell>

<Paragraph>Type tile here</Paragraph>

</TableCell>

<TableCell>

<Paragraph>Row Content Display Area</Paragraph>

</TableCell>

</TableRow>

<TableRow>

<TableCell>

<Paragraph>Type tile here</Paragraph>

</TableCell>

<TableCell>

<Paragraph>Row Content Display Area</Paragraph>

</TableCell>

</TableRow>

</TableRowGroup>

</Table>

·         ListItem元素:以列表的方式展现内容。通过MarkStyle可以改变其列表风格。

<List MarkerStyle="Decimal">

<ListItem>

<Paragraph>this area shows as list item</Paragraph>

</ListItem>

<ListItem>

<Paragraph>this area shows as list item</Paragraph>

</ListItem>

<ListItem>

<Paragraph>this area shows as list item</Paragraph>

</ListItem>

<ListItem>

<Paragraph>this area shows as list item</Paragraph>

</ListItem>

</List>

·         LineBreak:添加一个换行标记。

Figure 8: 在Flow Document中应用Table, ListItem和Floater.

Flow Document提供了一系列的默认导航、分页、搜索功能,并可以通过以类似HTML的方式展现内容。更为客观的是,由于支持内嵌WPF Control,我们可以提供更多的可控功能。

附加示例代码:下载

WPF中使用流文档的更多相关文章

  1. WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心

    原文:WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心 流文档是WPF中的一种独特的文档承载格式,它的书写和呈现方式都很像HTML,它也几乎具备了HTML的绝大多数优势,并提供了更 ...

  2. WPF 流文档

    WPF文本显示: WPF面向的是UI展现,而文本显示无疑是UI层中的重要功能之中的一个.WPF提供了XPS (XML 文件规范) 和Flow Document (流文档) 来在不同的场景下展现或者操作 ...

  3. DOM和SAX是应用中操纵XML文档的差别

    查看原文:http://www.ibloger.net/article/205.html DOM和SAX是应用中操纵XML文档的两种主要API.它们分别解释例如以下:          DOM.即Do ...

  4. wpf采用Xps实现文档显示、套打功能

    原文:wpf采用Xps实现文档显示.套打功能 近期的一个项目需对数据进行套打,用户要求现场不允许安装office.页面预览显示必须要与文档完全一致,xps文档来对数据进行处理.Wpf的Document ...

  5. 如何在程序中给word文档加上标和下标

    如何在程序中给word文档加上标和下标 上标或下标是一个小于普通行格式的数字,图形,标志或者指示通常它的设置与行相比偏上或偏下.下标通常显示于或者低于基准线,而上标则高于.上标和下标通常被用于表达公式 ...

  6. C# 中使用Word文档对图像进行操作

    C# 中使用Word文档对图像进行操作 Download Files: ImageOperationsInWord.zip 简介 在这篇文章中我们可以学到在C#程序中使用一个Word文档对图像的各种操 ...

  7. ABBYY PDF Transformer+从文件选项中创建PDF文档的教程

    可使用OCR文字识别软件ABBYY PDF Transformer+从Microsoft Word.Microsoft Excel.Microsoft PowerPoint.HTML.RTF.Micr ...

  8. Indri中的动态文档索引技术

    Indri中的动态文档索引技术 戴维 译 摘要: Indri 动态文档索引的实现技术,支持在更新索引的同时处理用户在线查询请求. 文本搜索引擎曾被设计为针对固定的文档集合进行查询,对不少应用来说,这种 ...

  9. openoffice转换过程中遇到繁体字文档转换失败的问题

    今天发现上线的文档转换功能中存在一个文档转换不成功,查看后台日志标志文档无法加载成功,提示日志如下: INFO: connected Jul 08, 2015 2:50:33 PM com.artof ...

随机推荐

  1. [ 转载 ] Python Web 框架:Django、Flask 与 Tornado 的性能对比

    本文的数据涉及到我面试时遇到过的问题,大概一次 http 请求到收到响应需要多少时间.这个问题在实际工作中与框架有比较大的关系,因此特别就框架的性能做了一次分析. 这里使用 2016 年 6 月 9 ...

  2. Django-ContentType-signals 实现牛逼玩法

    一.ContentType 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的 ...

  3. JFreeChart 之折线图

    JFreeChart 之折线图 一.JFreeChart 简介 JFreeChart是JAVA平台上的一个开放的图表绘制类库.它完全使用JAVA语言编写,是为applications, applets ...

  4. 「BZOJ 3645」小朋友与二叉树

    「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...

  5. [TC13761]Mutalisk

    [TC13761]Mutalisk 题目大意: 有\(n(n\le20)\)个坏人,第\(i\)个坏人的血量为\(A_i(A_i\le60)\).你可以每次攻击\(3\)个坏人,并分别造成\(9\)点 ...

  6. mysql分页查询优化(索引延迟关联)

    对于web后台报表导出是一种常见的功能点,实际对应服务后端即数据库的排序分页查询.如下示例为公司商户积分报表导出其中一个sql ,当大批量的导出请求进入时候,mysql的cpu急剧上升瞬间有拖垮库的风 ...

  7. 使用 IntraWeb (19) - 基本控件之 TIWTreeView

    这是个饱受非议的控件; 我通过尝试, 理解了非议, 也能理解作者. 总之向作者的思路靠拢吧, 还是不错的. TIWTreeView 所在单元及继承链: IWCompTreeview.TIWTreeVi ...

  8. 关于ConcurrentDictionary的线程安全

    ConcurrentDictionary是.net BCL的一个线程安全的字典类,由于其方法的线程安全性,使用时无需手动加锁,被广泛应用于多线程编程中.然而,有的时候他们并不是如我们预期的那样工作. ...

  9. JTAG – A technical overview and Timing

    This document provides you with interesting background information about the technology that underpi ...

  10. Redis源代码分析(三十五)--- redis.c服务端的实现分析(2)

    在Redis服务端的代码量真的是比較大,假设一个一个API的学习怎么实现,无疑是一种效率非常低的做法,所以我今天对服务端的实现代码的学习,重在他的运行流程上.而对于他的模块设计在上一篇中我已经分析过了 ...