WPF,Silverlight与XAML读书笔记第四十三 - 多媒体支持之文本与文档

时间:2022-07-18 16:56:50

说明:本系列基本上是《WPF揭秘》的读书笔记。在结构安排与文章内容上参照《WPF揭秘》的编排,对内容进行了总结并加入一些个人理解。

Glyphs对象(WPF,Silverlight)

Glyphs对象可以同时用来创建有字体(或者说有固定字形)的文字内容与没有字体(没有定义固定字形,如Wingdings或Unicode)的文字内容。

注意,当在Silverlight环境中使用Glyphs对象时,由于字体文件会被下载到目标机器,所以作为开发人员需要确保有分发这个字体的权利。

Glyphs使用下面这些属性来控制文本内容,FontUri用来指定字体的位置。使用Indices或者UnicodeString属性来指定文字的内容,当使用Indices时可以使用一组分号分隔数字来定义文字间距等信息。FontRenderingEmSize属性用来定义文字的大小,使用StyleSimulations可以定义字体的样式,这个属性接受的值包括BoldSimulation、ItalicSimulation、BoldItalicSimulation或None。

下面的例子用来输出一段使用webdings字体的文本内容,webdings.ttf这个字体文件需要被放置在与Silvelight相同的文件夹中,以便可以分发到客户端,再次提醒你需要对所分发的字体拥有授权。

 <Glyphs FontUri="webdings.ttf" Indices="133;134;135" Fill="Black" FontRenderingEmSize="48"/>

TextBlock(WPF, Silverlight)

这个对象的使用非常简单,用来展示一行或多行文字,与Glyphs不同,TextBlock使用内置支持的字体,如对于Silverlight默认支持如下9中字体:

  • Arial
  • Arial Black
  • Comic Sans MS
  • Courier New
  • Georgia
  • Lucida Grande/Lucida Sans Unicode
  • Times New Roman
  • Trebuchet MS
  • Verdana

使用TextBlock的FontFamily属性来设置字体,以上9种字体可以实现在任何系统浏览器环境下均可用,如果你指定了一个这9种之外的字体,运行时首先会在系统中查找这种字体如果找到则使用,反之将使用这9种中最接近的字体来代替。

FontSize属性用来定义字体的大小,FontStyle用来定义字体的样式,值可以是Normal或Italic。FontWeight属性用来定义字体的粗细,可接受的参数包括:Thin、ExtraLight、Light、Normal、Medium、SemiBold、Bold、ExtraBold、Black与ExtraBlack。TextDecoration属性用来确定文字是否使用下划线,接受的两个值为Underline和None。TextWrapping属性用来确定TextBlock中文字的换行方式,当设置为NoWrap时,文本内容会显示在一行里,而如果文本超出了TextBlock的宽度时内容会被截断。当设置为Wrap时,如果文本内容超过TextBlock的宽度时,会换到一个新行上。由于TextWrapping的不同设置会使内容或是被切断或是增加新行,从而影响到文本框的大小,这时可以使用TextBlock提供的ActualWidth与ActualHeight得到TextBlock的实际大小。

Runs标签

Runs标签用来改变TextBlock中文字的排版与样式,定义在TextBlock中的文本会使用TextBlock中定义的样式同样定义在Runs标签中的文本会使用Runs中定义的样式。通过下面的示例代码就可以很容易的明白:

 <TextBlock FontFamily="Arial" Width="500" Text="Arial Text" Foreground="Pink" FontWeight="UltraBold">
<Run Foreground="Blue" FontFamily="Comic Sans MS" FontSize="22">
Comic Sans MS Larger
</Run>
<Run Foreground="Teal" FontFamily="Verdana" FontSize="12" FontStyle="Italic">
Verdana Italic
</Run>
</TextBlock>

文字样式如下图:

WPF,Silverlight与XAML读书笔记第四十三 - 多媒体支持之文本与文档

可以看到文本的样式被分为3部分。

LineBreak行分割标签

LineBreak也很简单就是插入一个行分割符,我们把上面的例子改一下:

 <TextBlock FontFamily="Arial" Width="500" Text="Arial Text" Foreground="Pink" FontWeight="UltraBold">
<Run Foreground="Blue" FontFamily="Comic Sans MS" FontSize="22">
Comic Sans MS Larger
</Run>
<LineBreak/>
<Run Foreground="Teal" FontFamily="Verdana" FontSize="12" FontStyle="Italic">
Verdana Italic
</Run>
</TextBlock>

新的效果图:

WPF,Silverlight与XAML读书笔记第四十三 - 多媒体支持之文本与文档

很明显的第3段文字被转到一个新行中。

文档

这一部分我们重点介绍WPF的流文档,流文档用FlowDocument元素来表示,其中包含文本或其它内容,通过调整这些内容,流文档可以充分利用给定的空间。

提示:与WPF中的流文档不同,XPS属于固定布局文档,XPS在屏幕上看起来总是一致的。.NET Framework也包含创建与查看XPS的API,位于System.Windows.Xps和System.Windows.Documents命名空间下。

FlowDocument是一个FrameworkContentElement(FixedDocument也是),而FrameworkContentElement则是内容居中的FrameworkElement。FrameworkContentElement可以支持数据绑定,动画等WPF机制,但无法参与WPF布局。当FrameworkContentElement显示在屏幕中时最终会被放入FrameworkElement中。

TextElement用来表示可以放入FlowDocument的内容,这是一个抽象类,位于System.Windows.Documents命名空间下。下面着重介绍TextElement的一系列子类,及怎样将它们组合构建需要的FlowDocument。

两种最主要的TextElement分别是Block和Inline,它们都是TextElement的抽象子类。Block表示一个不可分割的矩形区域(跨页除外),Inline通常占据一个非矩形区域,从一行结尾到下一行开头。FlowDocument只支持Block作为其直接元素。FlowDocument提供一个BlocksCollection类型的Blocks属性作为内容属性,我们可以直接使用各种Block填充FlowContent。

Block

WPF提供了5种不同的Block

  • Paragraph

    Paragraph中包含了需要放在FlowDocment的主要内容,Paragraph可包含一个Inline的集合。你会看到Paragraph中包含了一些文本但这些文本都位于一个名为Run的Inline元素中。

  • Section

    用于将多个Block组合在一起,方便批量放置Block的Background或Foreground。

  • List

    将ListItem元素的集合呈现为各种形式的列表。每个ListItem中可以包含一个Block元素,而这个Block元素通常为Paragraph。TextMarkerStyle类型的MarkStyle属性用于设置列表的样式,对于符号列表可设置为Box,Circle,Disc或Square,对于数字列表可设置为Decimal,LowerLatin,UpperLatin,LowerRoman和UpperRoman。设置为None表示一个普通列表。

  • Table

    实现一个类似HTML Table的表格,每个单元格中可包含一个Block元素。

  • BlockUIContainer

    用于将各种WPF元素,不管是Image,包含视频的MediaElement,Button或包含3D内容的Viewport3D放入一个FlowDocument中。

Inline

前文已经提到过Inline是用来填充Paragraph的元素,最常用的一种Inline元素为Run,该元素有一个StringText类型的属性,与一个接受字符串的构造函数,任何一个Inline的子元素都是一个Inline集合,所以Inline可以互相嵌套。几种不同的Inline如下:

  • Span

Span一般表示有特殊效果的文本,常见的几种Span为

  • Bold
  • Italic
  • Underline
  • Hyperlink
  • Anchored Block

AnchoredBlock抽象类有两个子类Figure和Floater,它们都是专门为包含Block而设计的。

  • Figure

    Figure类似一个小型的FlowDocument,可以嵌入外部FlowDocument并且与外部FlowDocument是隔离的。外面的FlowDocument会将Figure包围在中间,Figure在FlowDocument中的位置可以通过其HorizontalAnchor和VerticalAnchor属性设置。这两个属性的默认值分别为ColumnRight和ParagraphTop。

    • Floater:

      Floater是一种轻量的Figure,其设有HorizontalAnchor和VerticalAnchor两个属性,取而代之是一个简单的HorizontalAlignment属性,其有Left,Center,Right或Stretch四个属性值。

  • LineBreak

这个作用很好理解,就是换行。

提示:添加换页符的方法是,设置后一页Paragraph(包括Sectioin,List等)的BreakPageBefore属性为true。

  • InlineUIContainer

其除了不能放在Paragraph的最后外,其余特性与BlockUIContainer几乎完全一致。

FlowDocument的读写

如果我们需要编辑一个FlowDocument,可以将其放在一个RichTextBox中,也可以将RichTextBox的IsReadOnly设为true。防止用户编辑。

WPF另外提供了三种专门用于显示FlowDocument供阅读的控件。

  • FlowDocumentScrollViewer:将文档显示在一个带有滚动条的连续文件,类似于在IE中浏览网页的效果。需要将IsToolBarVisible设为true来启用缩放。
  • FlowDocumentPageViewer:会把文档分成一个个页,该模式类似Word中的"全屏阅读"模式。
  • FlowDocumentReader:这是XAML中的FlowDocument默认使用的控件,其内置了FlowDocumentScrollViewer和FlowDocumentPageViewer两个控件,并内建文本搜索等额外功能,默认支持缩放。

使用注释

前文介绍的WPF提供了三个FlowDocument阅读控件都支持注释的显式与添加,支持这个功能的为System.Windows.Annotations命名空间下的AmotationService类,该类提供了5个与注释有关的命令。

  • CreateTextStickyNoteCommand:在选中的文本上附加一个新的基于文本的StickyNoteControl作为注释。
  • CreateInkStickyNoteCommand:在选中的文本上附加一个新的基于墨水的StickyNoteControl作为注释。
  • DeleteStickyNoteCommand:删除选中的一个或多个StickyNoteControl。
  • CreateHighlightCommand:用传入的命令突出显示选中的文本。
  • ClearHighlightsCommand:从选中的文本中移除所有突出显示的内容。

另外,我们还需要自己添加控件,并将控件与上述 Command关联起来控制FlowDocument中的注释。WPF会自动根据上下文启用或禁用我们添加的控件。下面的XAML展示了上述控件的定义:

 <Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:a="clr-namespace:System.Windows.Annotations;assembly=PresentationFramework"
x:Class="Window1" Initialized="OnInitialized" Closed="OnClosed">
<Canvas>
<StackPanel Orientation="Horizontal">
<Button Command="a:AnnotationService.CreateTextStickyNoteCommand" CommandTarget="{Binding ElementName=reader}">
Create Text Note
</Button>
<Button Command="a:AnnotationService.CreateInkStickyNoteCommand" CommandTarget="{Binding ElementName=reader}">
Create Ink Note
</Button>
<Button Command="a:AnnotationService.DeleteStickyNotesCommand" CommandTarget="{Binding ElementName=reader}">
Remove Note
</Button>
<Button Command="a:AnnotationService.CreateHighlightCommand" CommandTarget="{Binding ElementName=reader}">
Create Yellow Highlight
</Button>
<Button Command="a:AnnotationService.ClearHighlightsCommand" CommandTarget="{Binding ElementName=reader}">
Remove Highlight
</Button>
</StackPanel> <FlowDocumentReader x:Name="reader">
<FlowDocument>
</FlowDocument>
</FlowDocumentReader>
</Canvas>
</Window>

下面的C#代码展示上述XAML中使用的OnInitialized和OnCloseed方法:

 Stream stream;

 protected void OnInitialized(object sender, EventArgs e)
{
// Enable and load annotations
AnnotationService service = AnnotationService.GetService(reader);
if (service == null)
{
stream = new FileStream("storage.xml", FileMode.OpenOrCreate);
service = new AnnotationService(reader);
AnnotationStore store = new XmlStreamStore(stream);
service.Enable(store);
}
} protected void OnClosed(object sender, EventArgs e)
{
// Disable and save annotations
AnnotationService service = AnnotationService.GetService(reader);
if (service != null && service.IsEnabled)
{
service.Store.Flush();
service.Disable();
stream.Close();
}
}

这些代码主要完成了AnnotationService的启用与禁用,加载与保存注释文件(xml)。

提示:如果感觉StickyNoteControl默认的外观不是你想要的,可以通过自定义模板来改变其样式。

本文完

参考:

《WPF揭秘》