Back to Devexpress

Positions and Ranges

officefileapi-15303-word-processing-document-api-word-processing-document-positions-and-ranges.md

latest18.9 KB
Original Source

Positions and Ranges

  • Apr 23, 2025
  • 7 minutes to read

Position and range are key entities in Word Processing Document API. They define the location of every object in a document model.

Position

Position (the DocumentPosition object) is a zero-based index of every symbol in a document. Each position identifies a possible placement for a caret. Position 0 is the beginning of a document and precedes the first character. When the caret moves to the next character, it moves to position 1 and so on.

Obtain a Position

The following code sample calls the SubDocument.CreatePosition method to obtain the document position at the given index and inserts a text in it:

csharp
using (var wordProcessor = new RichEditDocumentServer())
{
    Document document = wordProcessor.Document;
    DocumentPosition pos1 = document.CreatePosition(2);
    document.InsertText(pos1,"The Word Processing Document API is a non-visual .NET library.\r
    It allows you to automate frequent word processing tasks.\n");
}
vb
Using wordProcessor = New RichEditDocumentServer()
    Dim document As Document = wordProcessor.Document
    Dim pos1 As DocumentPosition = document.CreatePosition(2)
    document.InsertText(pos1, "The Word Processing Document API is a non-visual .NET library. It allows you to automate frequent word processing tasks")
End Using

You can use DocumentPosition objects to insert other elements into a document. The table below lists APIs that use a position as a parameter or returns a DocumentPosition object.

APIDescription
SubDocument.InsertTextInserts a given text string at the specified position.
SubDocument.InsertDocumentContentInserts content from a range, stream or text string at the specified position.
ParagraphCollection.InsertInsert a new paragraph at the specified position.
Document.InsertSectionInserts a section break at the given position.
FieldCollection.CreateCreates a new field at the specified position.
BookmarkCollection.CreateCreates a new bookmark at the given position.
FormFieldCollection.InsertCheckBoxCreates a new checkbox at the given position.
ShapeCollection.InsertPictureInserts a new image at the given position.
ShapeCollection.InsertTextBoxInserts a new text box at the given position.
CommentCollection.CreateCreates a comment anchored to the specified position
TableCollection.CreateInserts a new table with the given number of rows and columns in the specified position.

The following code snippet appends an image at the end of the document:

csharp
document.Images.Insert(document.Range.End,
DocumentImageSource.FromFile("Documents//DevExpress.png"));
vb
document.Images.Insert(document.Range.End,
DocumentImageSource.FromFile("Documents//DevExpress.png"))

Range

The range (the DocumentRange object) is an interval between two positions (DocumentRange.Start and DocumentRange.End). The difference between them is equal to DocumentRange.Length.

Obtain a Range

Use the SubDocument.CreateRange method to create a new DocumentRange object with the specified start and end positions.

The following API allows you to obtain a range associated with document elements or obtain elements from a specified range:

ObjectObtain a Range Related to an ElementRetrieve an Element from a Range
TextSubDocument.RangeSubDocument.GetText
SubDocument.GetRtfText
SubDocument.GetHtmlText
SubDocument.GetMhtText
SubDocument.GetDocxBytes
SubDocument.GetDocBytes
ParagraphParagraph.RangeParagraphs.Get
SectionSection.RangeDocument.GetSection
Image and ShapeShape.RangeShapes.Get
TableTable.RangeTables.Get
HyperlinkHyperlink.RangeHyperlinks.Get
BookmarkBookmark.RangeBookmarks.Get
CommentComment.RangeComments.Get
FieldField.RangeFields.Get

The following code sample retrieves all images from the document and moves the first image to the header:

csharp
Document document = wordProcessor.Document;
if (document.Images.Count != 0)
{
    // Obtain all images
    ReadOnlyDocumentImageCollection images = document.Images.Get(document.Range);

    // Start the header update
    SubDocument header = document.Sections[0].BeginUpdateHeader();

    // Insert the retrieved image in the header
    header.Images.Insert(header.Range.Start, images[0].Image.NativeImage);
    header.EndUpdate();

    // Remove the image from its initial place
    document.Delete(images[0].Range);
}
vb
Dim document As Document = wordProcessor.Document

If document.Images.Count <> 0 Then
    ' Obtain all images
    Dim images As ReadOnlyDocumentImageCollection = document.Images.Get(document.Range)

    ' Start the header's update
    Dim header As SubDocument = document.Sections(0).BeginUpdateHeader()

    ' Insert the retrieved image in the header
    header.Images.Insert(header.Range.Start, images(0).Image.NativeImage)
    header.EndUpdate()

    ' Remove the image from its initial place
    document.Delete(images(0).Range)
End If

How Content Modifications Affect Ranges

When you modify content within a range, the range can expand or shrink automatically.

If you append a single line to a document and change its format options, the format is applied to the new content only.

Tip

Refer to the following article for more information on how to format text: Text Formatting

csharp
using (RichEditDocumentServer server = new RichEditDocumentServer())
{
    Document document = server.Document;

    //Append the line
    DocumentRange newRange = document.AppendText("Word Processing Document API\r\n");

    //Change the range's format options
    CharacterProperties characterProperties = document.BeginUpdateCharacters(newRange);
    characterProperties.ForeColor = Color.DarkGray;
    characterProperties.FontSize = 16;
    characterProperties.FontName = "Georgia";
    characterProperties.Italic = true;
    document.EndUpdateCharacters(characterProperties);

    server.SaveDocument("result.docx", DocumentFormat.Docx);
}
vb
Using server As New RichEditDocumentServer()
    Dim document As Document = server.Document

    'Append the line
    Dim newRange As DocumentRange = document.AppendText("Word Processing Document API" & ControlChars.CrLf)

    'Change the range's format options
    Dim characterProperties As CharacterProperties = document.BeginUpdateCharacters(newRange)
    characterProperties.ForeColor = Color.DarkGray
    characterProperties.FontSize = 16
    characterProperties.FontName = "Georgia"
    characterProperties.Italic = True
    document.EndUpdateCharacters(characterProperties)

    server.SaveDocument("result.docx", DocumentFormat.Docx)

End Using

If you sequentially append multiple fragments to a document, the DocumentRange object may expand with each new added fragment. The examples below demonstrate the possible results and two ways to resolve these issues.

Append two lines of text and then change the range’s formatting, as shown below:

csharp
using (RichEditDocumentServer server = new RichEditDocumentServer())
{
    Document document = server.Document;

    //Append the first line
    DocumentRange newRange = document.AppendText("Word Processing Document API\r\n");

    //Append the second line
    document.AppendText("The Word Processing Document API is a non-visual .NET library.\r " +
        "It allows you to automate frequent word processing tasks.\n");

    //Change the range's format options
    CharacterProperties characterProperties = document.BeginUpdateCharacters(newRange);
    characterProperties.ForeColor = Color.DarkGray;
    characterProperties.FontSize = 16;
    characterProperties.FontName = "Georgia";
    characterProperties.Italic = true;
    document.EndUpdateCharacters(characterProperties);

    server.SaveDocument("result.docx", DocumentFormat.Docx);
}
vb
Using server As New RichEditDocumentServer()
    Dim document As Document = server.Document

    'Append the first line
    Dim newRange As DocumentRange = document.AppendText("Word Processing Document API" & ControlChars.CrLf)

    'Append the second line
    document.AppendText("The Word Processing Document API is a non-visual .NET library." & ControlChars.Cr & " " & "It allows you to automate frequent word processing tasks." & ControlChars.Lf)

    'Change the range's format options
    Dim characterProperties As CharacterProperties = document.BeginUpdateCharacters(newRange)
    characterProperties.ForeColor = Color.DarkGray
    characterProperties.FontSize = 16
    characterProperties.FontName = "Georgia"
    characterProperties.Italic = True
    document.EndUpdateCharacters(characterProperties)

    server.SaveDocument("result.docx", DocumentFormat.Docx)
End Using

When you execute this code, it changes the format of all the text.

Solution #1

Change the format options before inserting new content to avoid this behavior. In this case, the new content remains unformatted.

csharp
using (RichEditDocumentServer server = new RichEditDocumentServer())
{
    Document document = server.Document;

    //Append the first line
    DocumentRange newRange = document.AppendText("Word Processing Document API\r\n");

    //Apply formatting for the first line
    CharacterProperties characterProperties = document.BeginUpdateCharacters(newRange);
    characterProperties.ForeColor = Color.DarkGray;
    characterProperties.FontSize = 16;
    characterProperties.FontName = "Georgia";
    characterProperties.Italic = true;
    document.EndUpdateCharacters(characterProperties);

    //Append the second line
    document.AppendText("The Word Processing Document API is a non-visual .NET library.\r " +
    "It allows you to automate frequent word processing tasks.\n");

    server.SaveDocument("result.docx", DocumentFormat.Docx);
}
vb
Using server As New RichEditDocumentServer()
    Dim document As Document = server.Document

    'Append the first line
    Dim newRange As DocumentRange = document.AppendText("Word Processing Document API" & ControlChars.CrLf)

    'Apply formatting for the first line
    Dim characterProperties As CharacterProperties = document.BeginUpdateCharacters(newRange)
    characterProperties.ForeColor = Color.DarkGray
    characterProperties.FontSize = 16
    characterProperties.FontName = "Georgia"
    characterProperties.Italic = True
    document.EndUpdateCharacters(characterProperties)

    'Append the second line
    document.AppendText("The Word Processing Document API is a non-visual .NET library." & ControlChars.Cr & " " & "It allows you to automate frequent word processing tasks." & ControlChars.Lf)

    server.SaveDocument("result.docx", DocumentFormat.Docx)
End Using

Solution #2

Another way to format the initial content is to store the target range’s position and length and create a new DocumentRange object.

The following code sample appends two lines to the document, but changes the format options only for the first line.

csharp
using (RichEditDocumentServer server = new RichEditDocumentServer())
{
    Document document = server.Document;

    //Append the first line
    DocumentRange newRange = document.AppendText("Word Processing Document API.\r\n");

    //Preserve the range's start position and length
    int rangeStart = newRange.Start.ToInt();
    int rangeLength = newRange.Length;

    //Append the second line
    document.AppendText("The Word Processing Document API is a non-visual .NET library.\r " +
        "It allows you to automate frequent word processing tasks.\n");

    //Recreate the initial range
    DocumentRange formattedRange = document.CreateRange(rangeStart, rangeLength);

    //Format the target range
    CharacterProperties characterProperties = document.BeginUpdateCharacters(formattedRange);
    characterProperties.ForeColor = Color.DarkGray;
    characterProperties.FontSize = 16;
    characterProperties.FontName = "Georgia";
    characterProperties.Italic = true;
    document.EndUpdateCharacters(characterProperties);

    server.SaveDocument("result.docx", DocumentFormat.Docx);
}
vb
Using server As New RichEditDocumentServer()
    Dim document As Document = server.Document

    'Append the first line
    Dim newRange As DocumentRange = document.AppendText("Word Processing Document API." & ControlChars.CrLf)

    'Preserve the range's start and length
    Dim rangeStart As Integer = newRange.Start.ToInt()
    Dim rangeLength As Integer = newRange.Length

    'Append the second line
    document.AppendText("The Word Processing Document API is a non-visual .NET library." & ControlChars.Cr & " " & "It allows you to automate frequent word processing tasks." & ControlChars.Lf)

    'Recreate the initial range
    Dim formattedRange As DocumentRange = document.CreateRange(rangeStart, rangeLength)

    'Format the target range
    Dim characterProperties As CharacterProperties = document.BeginUpdateCharacters(formattedRange)
    characterProperties.ForeColor = Color.DarkGray
    characterProperties.FontSize = 16
    characterProperties.FontName = "Georgia"
    characterProperties.Italic = True
    document.EndUpdateCharacters(characterProperties)

    server.SaveDocument("result.docx", DocumentFormat.Docx)
End Using

See Also

Word Processing Document API Examples

Text Formatting