• WPF,Silverlight与XAML读书笔记第四十三


    说明:本系列基本上是《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相同的文件夹中,以便可以分发到客户端,再次提醒你需要对所分发的字体拥有授权。

    1 <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中定义的样式。通过下面的示例代码就可以很容易的明白:

    1 <TextBlock FontFamily="Arial" Width="500" Text="Arial Text" Foreground="Pink" FontWeight="UltraBold">
    2     <Run Foreground="Blue" FontFamily="Comic Sans MS" FontSize="22">
    3         Comic Sans MS Larger
    4     </Run>
    5     <Run Foreground="Teal" FontFamily="Verdana" FontSize="12" FontStyle="Italic">
    6         Verdana Italic
    7     </Run>
    8 </TextBlock>

    文字样式如下图:

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

    LineBreak行分割标签

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

    1 <TextBlock FontFamily="Arial" Width="500" Text="Arial Text" Foreground="Pink" FontWeight="UltraBold">
    2     <Run Foreground="Blue" FontFamily="Comic Sans MS" FontSize="22">
    3         Comic Sans MS Larger
    4     </Run>
    5     <LineBreak/>
    6     <Run Foreground="Teal" FontFamily="Verdana" FontSize="12" FontStyle="Italic">
    7         Verdana Italic
    8     </Run>
    9 </TextBlock>

    新的效果图:

    很明显的第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展示了上述控件的定义:

     1 <Window   
     2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4     xmlns:a="clr-namespace:System.Windows.Annotations;assembly=PresentationFramework"
     5     x:Class="Window1" Initialized="OnInitialized" Closed="OnClosed">
     6     <Canvas>
     7         <StackPanel Orientation="Horizontal">
     8             <Button Command="a:AnnotationService.CreateTextStickyNoteCommand" CommandTarget="{Binding ElementName=reader}">
     9                 Create Text Note
    10             </Button>
    11             <Button Command="a:AnnotationService.CreateInkStickyNoteCommand" CommandTarget="{Binding ElementName=reader}">
    12                 Create Ink Note
    13             </Button>
    14             <Button Command="a:AnnotationService.DeleteStickyNotesCommand" CommandTarget="{Binding ElementName=reader}">
    15                 Remove Note
    16             </Button>
    17             <Button Command="a:AnnotationService.CreateHighlightCommand"  CommandTarget="{Binding ElementName=reader}">
    18                 Create Yellow Highlight
    19             </Button>
    20             <Button Command="a:AnnotationService.ClearHighlightsCommand" CommandTarget="{Binding ElementName=reader}">
    21                 Remove Highlight
    22             </Button>
    23         </StackPanel>
    24 
    25         <FlowDocumentReader x:Name="reader">
    26             <FlowDocument>
    27             </FlowDocument>
    28         </FlowDocumentReader>
    29     </Canvas>
    30 </Window>

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

     1 Stream stream;
     2 
     3 protected void OnInitialized(object sender, EventArgs e)
     4 {
     5     // Enable and load annotations
     6     AnnotationService service = AnnotationService.GetService(reader);
     7     if (service == null)
     8     {
     9         stream = new FileStream("storage.xml", FileMode.OpenOrCreate);
    10         service = new AnnotationService(reader);
    11         AnnotationStore store = new XmlStreamStore(stream);
    12         service.Enable(store);
    13     }
    14 }
    15 
    16 protected void OnClosed(object sender, EventArgs e)
    17 {
    18     // Disable and save annotations
    19     AnnotationService service = AnnotationService.GetService(reader);
    20     if (service != null && service.IsEnabled)
    21     {
    22         service.Store.Flush();
    23         service.Disable();
    24         stream.Close();
    25     }
    26 }

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

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

    本文完

    参考:

    《WPF揭秘》

  • 相关阅读:
    07-汤姆猫
    快捷键
    UIImageView属性
    UIImagePickerController
    UIDatePicker
    并发编程简介
    区别值类型数据和引用类型数据
    用条件属性而不是#if
    选择is或者as操作符而不是做强制类型转换
    始终使用属性(Property),而不是字段(Data Member)
  • 原文地址:https://www.cnblogs.com/lsxqw2004/p/4632194.html
Copyright © 2020-2023  润新知