用光标导航

在处理文档时,无论文档长短,您都需要浏览文档。使用虚拟光标导航表示在文档中的不同节点之间导航的能力。

在简短的文档中,在文档中移动非常简单,因为您甚至可以使用键盘的箭头键或单击鼠标将插入点定位到所需的位置,从而移动插入点。但是,一旦您有一个包含很多页的大型文档,这些基本技术就不够了。

本文介绍如何在文档中移动并使用虚拟光标导航到文档的不同部分。

检测当前光标位置

在开始浏览文档之前,您需要获取当前选定的节点。您可以使用 CurrentNode 属性获取光标在选定节点处的准确位置。此外,您可以使用 CurrentParagraphCurrentSection 属性获取当前选定的段落或当前选定的部分,而不是获取当前节点。

您使用 DocumentBuilder 执行的任何插入操作都将插入到 CurrentNode 之前。当当前段落为空或光标位于段落末尾之前时,CurrentNode 返回 null。

在文档中导航方法

编辑文本时,了解如何导航文档以及在文档中准确移动的位置非常重要。 Aspose.Words 允许您在文档中移动并导航到其不同的部分和部分 - 这类似于 Microsoft Word 中导航窗格的功能,无需滚动即可转到 Word 文档中的页面或标题。

主要方法是能够将光标位置移动到文档中的特定节点,您可以使用 MoveTo 方法来实现这一点。

以下代码示例演示如何将 DocumentBuilder 移动到文档中的不同节点:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Start a bookmark and add content to it using a DocumentBuilder.
builder.StartBookmark("MyBookmark");
builder.Writeln("Bookmark contents.");
builder.EndBookmark("MyBookmark");
// The node that the DocumentBuilder is currently at is past the boundaries of the bookmark.
Assert.AreEqual(doc.Range.Bookmarks[0].BookmarkEnd, builder.CurrentParagraph.FirstChild);
// If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this.
builder.MoveToBookmark("MyBookmark");
// Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it.
Assert.AreEqual(doc.Range.Bookmarks[0].BookmarkStart, builder.CurrentParagraph.FirstChild);
// We can move the builder to an individual node,
// which in this case will be the first node of the first paragraph, like this.
builder.MoveTo(doc.FirstSection.Body.FirstParagraph.GetChildNodes(NodeType.Any, false)[0]);
Assert.AreEqual(NodeType.BookmarkStart, builder.CurrentNode.NodeType);
Assert.IsTrue(builder.IsAtStartOfParagraph);
// A shorter way of moving the very start/end of a document is with these methods.
builder.MoveToDocumentEnd();
Assert.IsTrue(builder.IsAtEndOfParagraph);
builder.MoveToDocumentStart();
Assert.IsTrue(builder.IsAtStartOfParagraph);

但除了基本的 MoveTo 方法之外,还有更具体的方法。

导航到文档的开头或结尾

您可以使用 MoveToDocumentStartMoveToDocumentEnd 方法转到文档的开头或结尾。

以下代码示例演示如何将光标位置移动到文档的开头或结尾:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Move the cursor position to the beginning of your document.
builder.MoveToDocumentStart();
Console.WriteLine("\nThis is the beginning of the document.");
// Move the cursor position to the end of your document.
builder.MoveToDocumentEnd();
Console.WriteLine("\nThis is the end of the document.");

使用书签导航

您可以标记想要查找的位置并轻松地再次移动到该位置。您可以根据需要在文档中插入任意数量的书签,然后通过识别具有唯一名称的书签来浏览它们。您可以使用 MoveToBookmark 方法移动到书签。

以下代码示例演示如何将光标位置移动到书签:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Start a bookmark and add content to it using a DocumentBuilder.
builder.StartBookmark("MyBookmark");
builder.Writeln("Bookmark contents.");
builder.EndBookmark("MyBookmark");
// The node that the DocumentBuilder is currently at is past the boundaries of the bookmark.
Assert.AreEqual(doc.Range.Bookmarks[0].BookmarkEnd, builder.CurrentParagraph.FirstChild);
// If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this.
builder.MoveToBookmark("MyBookmark");
// Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it.
Assert.AreEqual(doc.Range.Bookmarks[0].BookmarkStart, builder.CurrentParagraph.FirstChild);
// We can move the builder to an individual node,
// which in this case will be the first node of the first paragraph, like this.
builder.MoveTo(doc.FirstSection.Body.FirstParagraph.GetChildNodes(NodeType.Any, false)[0]);

导航到表格单元格

您可以使用 MoveToCell 方法移动到表格单元格。此方法将使您能够将光标导航到特定表格中的任何单元格。此外,您还可以指定索引以将光标移动到 MoveToCell 方法内单元格中的任意位置或指定字符。

以下代码示例演示如何将光标位置移动到指定的表格单元格:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document(MyDir + "Tables.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
// Move the builder to row 3, cell 4 of the first table.
builder.MoveToCell(0, 2, 3, 0);
builder.Write("\nCell contents added by DocumentBuilder");
Table table = (Table)doc.GetChild(NodeType.Table, 0, true);
Assert.AreEqual(table.Rows[2].Cells[3], builder.CurrentNode.ParentNode.ParentNode);
Assert.AreEqual("Cell contents added by DocumentBuilderCell 3 contents\a", table.Rows[2].Cells[3].GetText().Trim());

导航到字段

您可以使用 MoveToField 方法移动到文档中的特定字段。此外,您还可以使用 MoveToMergeField 方法移动到特定的合并字段。

以下代码示例演示如何将文档生成器光标移动到特定字段:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Insert a field using the DocumentBuilder and add a run of text after it.
Field field = builder.InsertField("MERGEFIELD field");
builder.Write(" Text after the field.");
// The builder's cursor is currently at end of the document.
Assert.Null(builder.CurrentNode);
// We can move the builder to a field like this, placing the cursor at immediately after the field.
builder.MoveToField(field, true);
// Note that the cursor is at a place past the FieldEnd node of the field, meaning that we are not actually inside the field.
// If we wish to move the DocumentBuilder to inside a field,
// we will need to move it to a field's FieldStart or FieldSeparator node using the DocumentBuilder.MoveTo() method.
Assert.AreEqual(field.End, builder.CurrentNode.PreviousSibling);
builder.Write(" Text immediately after the field.");

导航到页眉或页脚

您可以使用 MoveToHeaderFooter 方法移至页眉或页脚的开头。

以下代码示例演示如何将文档生成器光标移动到文档页眉或页脚:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Specify that we want headers and footers different for first, even and odd pages.
builder.PageSetup.DifferentFirstPageHeaderFooter = true;
builder.PageSetup.OddAndEvenPagesHeaderFooter = true;
// Create the headers.
builder.MoveToHeaderFooter(HeaderFooterType.HeaderFirst);
builder.Write("Header for the first page");
builder.MoveToHeaderFooter(HeaderFooterType.HeaderEven);
builder.Write("Header for even pages");
builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);
builder.Write("Header for all other pages");
// Create two pages in the document.
builder.MoveToSection(0);
builder.Writeln("Page1");
builder.InsertBreak(BreakType.PageBreak);
builder.Writeln("Page2");
doc.Save(ArtifactsDir + "AddContentUsingDocumentBuilder.MoveToHeadersFooters.docx");

导航到某个部分或段落

您可以使用 MoveToParagraphMoveToSection 方法移至特定部分或段落。此外,您还可以指定索引以将光标移动到 MoveToParagraph 方法内段落中的任意位置或指定字符。

以下代码示例演示如何移动到文档中的特定部分和特定段落:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
doc.AppendChild(new Section(doc));
// Move a DocumentBuilder to the second section and add text.
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToSection(1);
builder.Writeln("Text added to the 2nd section.");
// Create document with paragraphs.
doc = new Document(MyDir + "Paragraphs.docx");
ParagraphCollection paragraphs = doc.FirstSection.Body.Paragraphs;
Assert.AreEqual(22, paragraphs.Count);
// When we create a DocumentBuilder for a document, its cursor is at the very beginning of the document by default,
// and any content added by the DocumentBuilder will just be prepended to the document.
builder = new DocumentBuilder(doc);
Assert.AreEqual(0, paragraphs.IndexOf(builder.CurrentParagraph));
// You can move the cursor to any position in a paragraph.
builder.MoveToParagraph(2, 10);
Assert.AreEqual(2, paragraphs.IndexOf(builder.CurrentParagraph));
builder.Writeln("This is a new third paragraph. ");
Assert.AreEqual(3, paragraphs.IndexOf(builder.CurrentParagraph));