在纸上写笔记或评论是一种常见的活动,我们几乎认为这是理所当然的。 这些“批注”是我们添加到文档中的,用于标记信息或突出显示感兴趣的项目,以便以后参考。 虽然在打印文档上编写笔记很容易和常见,但向电子文档添加个人批注的能力通常非常有限(如果一切可用)。
本主题回顾了几种常见类型的批注,特别是便笺和亮点,并说明了Microsoft批注框架如何通过 Windows Presentation Foundation (WPF) 文档查看控件在应用程序中促进这些类型的批注。 支持批注的 WPF 文档查看控件包括 FlowDocumentReader 和 FlowDocumentScrollViewer,以及派生自 DocumentViewerBase 的控件,如 DocumentViewer 和 FlowDocumentPageViewer。
便笺
平常的便笺是将信息写在小块彩纸上,随后将这张彩纸“粘贴”到文档。 数字便签为电子文档提供了相似的功能,并增加了灵活性,可以包含许多其他类型的内容,例如输入文本、手写笔记(例如,平板电脑上的“墨迹”笔触)或网络链接。
下图显示了突出显示、文本便笺以及墨迹便笺批注的一些示例。
以下示例显示了可用于在应用程序中启用批注支持的方法。
// ------------------------ StartAnnotations --------------------------
/// <summary>
/// Enables annotations and displays all that are viewable.</summary>
private void StartAnnotations()
{
// If there is no AnnotationService yet, create one.
if (_annotService == null)
// docViewer is a document viewing control named in Window1.xaml.
_annotService = new AnnotationService(docViewer);
// If the AnnotationService is currently enabled, disable it.
if (_annotService.IsEnabled == true)
_annotService.Disable();
// Open a stream to the file for storing annotations.
_annotStream = new FileStream(
_annotStorePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
// Create an AnnotationStore using the file stream.
_annotStore = new XmlStreamStore(_annotStream);
// Enable the AnnotationService using the new store.
_annotService.Enable(_annotStore);
}// end:StartAnnotations()
' ------------------------ StartAnnotations --------------------------
''' <summary>
''' Enables annotations and displays all that are viewable.</summary>
Private Sub StartAnnotations()
' If there is no AnnotationService yet, create one.
If _annotService Is Nothing Then
' docViewer is a document viewing control named in Window1.xaml.
_annotService = New AnnotationService(docViewer)
End If
' If the AnnotationService is currently enabled, disable it.
If _annotService.IsEnabled = True Then
_annotService.Disable()
End If
' Open a stream to the file for storing annotations.
_annotStream = New FileStream(_annotStorePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
' Create an AnnotationStore using the file stream.
_annotStore = New XmlStreamStore(_annotStream)
' Enable the AnnotationService using the new store.
_annotService.Enable(_annotStore)
End Sub
亮点
人们使用创造性的方法在标记纸文档时吸引人们对感兴趣的项目的关注,例如在句子中标记下划线、突出显示、盘旋字词,或在边距中绘制标记或表示法。 Microsoft Annotations Framework 中的突出显示批注具有类似的功能,用于标记在 WPF 文档查看控件中显示的信息。
下图演示了一个突出显示批注的示例。
用户通常通过先选择某些文本或感兴趣的项来创建批注,然后右键单击以显示批注选项 ContextMenu。 下面的示例演示了可扩展应用程序标记语言(XAML),你可以使用路由命令声明一个 ContextMenu,用户可以访问这些命令来创建和管理批注。
<DocumentViewer.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Copy" />
<Separator />
<!-- Add a Highlight annotation to a user selection. -->
<MenuItem Command="ann:AnnotationService.CreateHighlightCommand"
Header="Add Highlight" />
<!-- Add a Text Note annotation to a user selection. -->
<MenuItem Command="ann:AnnotationService.CreateTextStickyNoteCommand"
Header="Add Text Note" />
<!-- Add an Ink Note annotation to a user selection. -->
<MenuItem Command="ann:AnnotationService.CreateInkStickyNoteCommand"
Header="Add Ink Note" />
<Separator />
<!-- Remove Highlights from a user selection. -->
<MenuItem Command="ann:AnnotationService.ClearHighlightsCommand"
Header="Remove Highlights" />
<!-- Remove Text Notes and Ink Notes from a user selection. -->
<MenuItem Command="ann:AnnotationService.DeleteStickyNotesCommand"
Header="Remove Notes" />
<!-- Remove Highlights, Text Notes, Ink Notes from a selection. -->
<MenuItem Command="ann:AnnotationService.DeleteAnnotationsCommand"
Header="Remove Highlights & Notes" />
</ContextMenu>
</DocumentViewer.ContextMenu>
数据锚定
Annotations Framework 将批注绑定到用户选择的数据,而不仅仅是绑定到显示视图上的位置。 因此,如果文档视图更改(例如,当用户滚动显示窗口或者调整其大小时),批注将仍然跟随它绑定到的所选数据。 例如,下图演示了用户对文本选择所做的批注。 文档视图更改(滚动、调整大小、缩放或其他移动)时,突出显示批注将随原始数据选择一起移动。
匹配批注与批注对象
可以将批注与相应的批注对象匹配。 例如,请考虑具有批注窗格的简单文档阅读器应用程序。 批注窗格可能是一个列表框,显示定位到文档的批注列表中的文本。 如果用户在列表框中选择一个项,则应用程序将查看文档中相应批注对象定位到的段落。
以下示例演示如何实现用作批注窗格的此类列表框的事件处理程序。
void annotationsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Annotation comment = (sender as ListBox).SelectedItem as Annotation;
if (comment != null)
{
// IAnchorInfo info;
// service is an AnnotationService object
// comment is an Annotation object
info = AnnotationHelper.GetAnchorInfo(this.service, comment);
TextAnchor resolvedAnchor = info.ResolvedAnchor as TextAnchor;
TextPointer textPointer = (TextPointer)resolvedAnchor.BoundingStart;
textPointer.Paragraph.BringIntoView();
}
}
Private Sub annotationsListBox_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
Dim comment As Annotation = TryCast((TryCast(sender, ListBox)).SelectedItem, Annotation)
If comment IsNot Nothing Then
' service is an AnnotationService object
' comment is an Annotation object
info = AnnotationHelper.GetAnchorInfo(Me.service, comment)
Dim resolvedAnchor As TextAnchor = TryCast(info.ResolvedAnchor, TextAnchor)
Dim textPointer As TextPointer = CType(resolvedAnchor.BoundingStart, TextPointer)
textPointer.Paragraph.BringIntoView()
End If
End Sub
另一个示例方案涉及应用程序,这些应用程序允许通过电子邮件在文档阅读器之间交换批注和便笺。 此功能使这些应用程序能够将读取者导航到包含正在交换的批注的页面。