EditableRangeEnd class

Represents an end of an editable range in a Word document.

To learn more, visit the Aspose.Words Document Object Model (DOM) documentation article.

public sealed class EditableRangeEnd : Node


CustomNodeId { get; set; }Specifies custom node identifier.
virtual Document { get; }Gets the document to which this node belongs.
EditableRangeStart { get; }Corresponding EditableRangeStart, received by ID.
Id { get; set; }Specifies the identifier of the editable range.
virtual IsComposite { get; }Returns true if this node can contain other nodes.
NextSibling { get; }Gets the node immediately following this node.
override NodeType { get; }Returns EditableRangeEnd.
ParentNode { get; }Gets the immediate parent of this node.
PreviousSibling { get; }Gets the node immediately preceding this node.
Range { get; }Returns a Range object that represents the portion of a document that is contained in this node.


override Accept(DocumentVisitor)Accepts a visitor.
Clone(bool)Creates a duplicate of the node.
GetAncestor(NodeType)Gets the first ancestor of the specified NodeType.
GetAncestor(Type)Gets the first ancestor of the specified object type.
virtual GetText()Gets the text of this node and of all its children.
NextPreOrder(Node)Gets next node according to the pre-order tree traversal algorithm.
PreviousPreOrder(Node)Gets the previous node according to the pre-order tree traversal algorithm.
Remove()Removes itself from the parent.
ToString(SaveFormat)Exports the content of the node into a string in the specified format.
ToString(SaveOptions)Exports the content of the node into a string using the specified save options.


A complete editable range in a Word document consists of a EditableRangeStart and a matching EditableRangeEnd with the same Id.

EditableRangeStart and EditableRangeEnd are just markers inside a document that specify where the editable range starts and ends.

Use the EditableRange class as a “facade” to work with an editable range as a single object.

Currently editable ranges are supported only at the inline-level, that is inside Paragraph, but editable range start and editable range end can be in different paragraphs.


Shows how to limit the editing rights of editable ranges to a specific group/user.

public void Visitor()
    Document doc = new Document();
    doc.Protect(ProtectionType.ReadOnly, "MyPassword");

    DocumentBuilder builder = new DocumentBuilder(doc);
    builder.Writeln("Hello world! Since we have set the document's protection level to read-only," +
                    " we cannot edit this paragraph without the password.");

    // When we write-protect documents, editable ranges allow us to pick specific areas that users may edit.
    // There are two mutually exclusive ways to narrow down the list of allowed editors.
    // 1 -  Specify a user:
    EditableRange editableRange = builder.StartEditableRange().EditableRange;
    editableRange.SingleUser = "john.doe@myoffice.com";
    builder.Writeln($"This paragraph is inside the first editable range, can only be edited by {editableRange.SingleUser}.");

    Assert.AreEqual(EditorType.Unspecified, editableRange.EditorGroup);

    // 2 -  Specify a group that allowed users are associated with:
    editableRange = builder.StartEditableRange().EditableRange;
    editableRange.EditorGroup = EditorType.Administrators;
    builder.Writeln($"This paragraph is inside the first editable range, can only be edited by {editableRange.EditorGroup}.");

    Assert.AreEqual(string.Empty, editableRange.SingleUser);

    builder.Writeln("This paragraph is outside the editable range, and cannot be edited by anybody.");

    // Print details and contents of every editable range in the document.
    EditableRangePrinter editableRangePrinter = new EditableRangePrinter();



/// <summary>
/// Collects properties and contents of visited editable ranges in a string.
/// </summary>
public class EditableRangePrinter : DocumentVisitor
    public EditableRangePrinter()
        mBuilder = new StringBuilder();

    public string ToText()
        return mBuilder.ToString();

    public void Reset()
        mInsideEditableRange = false;

    /// <summary>
    /// Called when an EditableRangeStart node is encountered in the document.
    /// </summary>
    public override VisitorAction VisitEditableRangeStart(EditableRangeStart editableRangeStart)
        mBuilder.AppendLine(" -- Editable range found! -- ");
        mBuilder.AppendLine("\tID:\t\t" + editableRangeStart.Id);
        if (editableRangeStart.EditableRange.SingleUser == string.Empty)
            mBuilder.AppendLine("\tGroup:\t" + editableRangeStart.EditableRange.EditorGroup);
            mBuilder.AppendLine("\tUser:\t" + editableRangeStart.EditableRange.SingleUser);

        mInsideEditableRange = true;

        return VisitorAction.Continue;

    /// <summary>
    /// Called when an EditableRangeEnd node is encountered in the document.
    /// </summary>
    public override VisitorAction VisitEditableRangeEnd(EditableRangeEnd editableRangeEnd)
        mBuilder.AppendLine(" -- End of editable range --\n");

        mInsideEditableRange = false;

        return VisitorAction.Continue;

    /// <summary>
    /// Called when a Run node is encountered in the document. This visitor only records runs that are inside editable ranges.
    /// </summary>
    public override VisitorAction VisitRun(Run run)
        if (mInsideEditableRange) mBuilder.AppendLine("\t\"" + run.Text + "\"");

        return VisitorAction.Continue;

    private bool mInsideEditableRange;
    private readonly StringBuilder mBuilder;

See Also