光标导航

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

在一个简短的文档中,在文档中移动很简单,因为您可以移动插入点,即使使用键盘的箭头键或单击鼠标将插入点定位到您想要的任何位置。 但是一旦你有一个有很多页面的大文档,这些基本技术就会不足。

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

检测当前光标位置

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

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

在文档中导航方法

在编辑文本时,重要的是要知道如何导航文档以及在其中准确移动的位置。 Aspose.Words允许您在文档中移动并导航到其不同的部分和部分-这与Microsoft Word中的导航窗格的功能类似,可以在不滚动的情况下转到Word文档中的页面或标题。

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

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

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Start a bookmark and add content to it using a DocumentBuilder.
builder->StartBookmark(u"MyBookmark");
builder->Writeln(u"Bookmark contents.");
builder->EndBookmark(u"MyBookmark");
// The node that the DocumentBuilder is currently at is past the boundaries of the bookmark.
ASSERT_EQ(doc->get_Range()->get_Bookmarks()->idx_get(0)->get_BookmarkEnd(), builder->get_CurrentParagraph()->get_FirstChild());
// If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this.
builder->MoveToBookmark(u"MyBookmark");
// Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it.
ASSERT_EQ(doc->get_Range()->get_Bookmarks()->idx_get(0)->get_BookmarkStart(), builder->get_CurrentParagraph()->get_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->get_FirstSection()->get_Body()->get_FirstParagraph()->GetChildNodes(NodeType::Any, false)->idx_get(0));
ASSERT_EQ(NodeType::BookmarkStart, builder->get_CurrentNode()->get_NodeType());
ASSERT_TRUE(builder->get_IsAtStartOfParagraph());
// A shorter way of moving the very start/end of a document is with these methods.
builder->MoveToDocumentEnd();
ASSERT_TRUE(builder->get_IsAtEndOfParagraph());
builder->MoveToDocumentStart();
ASSERT_TRUE(builder->get_IsAtStartOfParagraph());

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

导航到文档的开头或结尾

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

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

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>(inputDataDir + u"Document.docx");
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Move the cursor position to the beginning of your document.
builder->MoveToDocumentStart();
builder->Writeln(u"This is the beginning of the document.");
// Move the cursor position to the end of your document.
builder->MoveToDocumentEnd();
builder->Writeln(u"This is the end of the document.");

使用书签导航

你可以标记一个你想找到的地方,然后很容易地再次移动到它。 您可以在文档中插入任意数量的书签,然后通过识别具有唯一名称的书签来浏览它们。 您可以使用MoveToBookmark方法移动到书签。

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

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Start a bookmark and add content to it using a DocumentBuilder.
builder->StartBookmark(u"MyBookmark");
builder->Writeln(u"Bookmark contents.");
builder->EndBookmark(u"MyBookmark");
// If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this.
builder->MoveToBookmark(u"MyBookmark");
// Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it.
ASSERT_EQ(doc->get_Range()->get_Bookmarks()->idx_get(0)->get_BookmarkStart(), builder->get_CurrentParagraph()->get_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->get_FirstSection()->get_Body()->get_FirstParagraph()->GetChildNodes(NodeType::Any, false)->idx_get(0));
ASSERT_EQ(NodeType::BookmarkStart, builder->get_CurrentNode()->get_NodeType());

导航到表格单元格

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

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

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>(inputDataDir + u"Tables.docx");
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Move the builder to row 3, cell 4 of the first table.
builder->MoveToCell(0, 2, 3, 0);
builder->Write(u"\nCell contents added by DocumentBuilder");
auto table = System::DynamicCast<Tables::Table>(doc->GetChild(NodeType::Table, 0, true));
ASSERT_EQ(table->get_Rows()->idx_get(2)->get_Cells()->idx_get(3), builder->get_CurrentNode()->get_ParentNode()->get_ParentNode());
ASSERT_EQ(table->get_Rows()->idx_get(2)->get_Cells()->idx_get(2)->GetText().Trim(), u"Cell contents added by DocumentBuilderCell 3 contents\a");

导航到字段

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

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

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Insert a field using the DocumentBuilder and add a run of text after it.
auto field = builder->InsertField(u"MERGEFIELD field");
builder->Write(u" Text after the field.");
// The builder's cursor is currently at end of the document.
ASSERT_EQ(builder->get_CurrentNode(), nullptr);
// 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_EQ(field->get_End(), builder->get_CurrentNode()->get_PreviousSibling());
builder->Write(u" Text immediately after the field.");

导航到页眉或页脚

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

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

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Specify that we want headers and footers different for first, even and odd pages.
builder->get_PageSetup()->set_DifferentFirstPageHeaderFooter(true);
builder->get_PageSetup()->set_OddAndEvenPagesHeaderFooter(true);
// Create the headers.
builder->MoveToHeaderFooter(HeaderFooterType::HeaderFirst);
builder->Write(u"Header for the first page");
builder->MoveToHeaderFooter(HeaderFooterType::HeaderEven);
builder->Write(u"Header for even pages");
builder->MoveToHeaderFooter(HeaderFooterType::HeaderPrimary);
builder->Write(u"Header for all other pages");
// Create two pages in the document.
builder->MoveToSection(0);
builder->Writeln(u"Page1");
builder->InsertBreak(BreakType::PageBreak);
builder->Writeln(u"Page2");
System::String outputPath = outputDataDir + u"DocumentBuilderMovingCursor.HeadersAndFooters.doc";
doc->Save(outputPath);

导航到部分或段落

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

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

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Create a blank document and append a section to it, giving it two sections.
auto doc = System::MakeObject<Document>();
doc->AppendChild(System::MakeObject<Section>(doc));
// Move a DocumentBuilder to the second section and add text.
auto builder = System::MakeObject<DocumentBuilder>(doc);
builder->MoveToSection(1);
builder->Writeln(u"Text added to the 2nd section.");
// Create document with paragraphs.
auto doc = System::MakeObject<Document>(inputDataDir + u"Paragraphs.docx");
auto paragraphs = doc->get_FirstSection()->get_Body()->get_Paragraphs();
ASSERT_EQ(paragraphs->get_Count(), 22);
// 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.
auto builder = System::MakeObject<DocumentBuilder>(doc);
ASSERT_EQ(paragraphs->IndexOf(builder->get_CurrentParagraph()), 0);
// You can move the cursor to any position in a paragraph.
builder->MoveToParagraph(0, 14);
ASSERT_EQ(paragraphs->IndexOf(builder->get_CurrentParagraph()), 2);
builder->Writeln(u"This is a new third paragraph. ");
ASSERT_EQ(paragraphs->IndexOf(builder->get_CurrentParagraph()), 3);