CommentRangeStart Class
Denotes the start of a region of text that has a comment associated with it.
Inheritance Hierarchy
SystemObject
  Aspose.WordsNode
    Aspose.WordsCommentRangeStart

Namespace: Aspose.Words
Assembly: Aspose.Words (in Aspose.Words.dll) Version: 19.11
Syntax
public sealed class CommentRangeStart : Node

The CommentRangeStart type exposes the following members.

Constructors
  NameDescription
Public methodCode exampleCommentRangeStart
Initializes a new instance of this class.
Properties
  NameDescription
Public propertyCode exampleDocument
Gets the document to which this node belongs.
(Inherited from Node.)
Public propertyCode exampleId
Specifies the identifier of the comment to which this region is linked.
Public propertyCode exampleIsComposite
Returns true if this node can contain other nodes.
(Inherited from Node.)
Public propertyCode exampleNextSibling
Gets the node immediately following this node.
(Inherited from Node.)
Public propertyCode exampleNodeType (Overrides NodeNodeType.)
Public propertyCode exampleParentNode
Gets the immediate parent of this node.
(Inherited from Node.)
Public propertyCode examplePreviousSibling
Gets the node immediately preceding this node.
(Inherited from Node.)
Public propertyCode exampleRange
Returns a Range object that represents the portion of a document that is contained in this node.
(Inherited from Node.)
Methods
  NameDescription
Public methodCode exampleAccept
Accepts a visitor.
(Overrides NodeAccept(DocumentVisitor).)
Public methodCode exampleClone (Inherited from Node.)
Public methodEquals (Inherited from Object.)
Public methodCode exampleGetAncestor(Type)
Gets the first ancestor of the specified object type.
(Inherited from Node.)
Public methodCode exampleGetAncestor(NodeType)
Gets the first ancestor of the specified NodeType.
(Inherited from Node.)
Public methodGetHashCode (Inherited from Object.)
Public methodCode exampleGetText
Gets the text of this node and of all its children.
(Inherited from Node.)
Public methodGetType (Inherited from Object.)
Public methodCode exampleNextPreOrder
Gets next node according to the pre-order tree traversal algorithm.
(Inherited from Node.)
Public methodCode examplePreviousPreOrder
Gets the previous node according to the pre-order tree traversal algorithm.
(Inherited from Node.)
Public methodCode exampleRemove
Removes itself from the parent.
(Inherited from Node.)
Public methodToString (Inherited from Object.)
Public methodCode exampleToString(SaveFormat)
Exports the content of the node into a string in the specified format.
(Inherited from Node.)
Public methodCode exampleToString(SaveOptions)
Exports the content of the node into a string using the specified save options.
(Inherited from Node.)
Remarks

To create a comment anchored to a region of text, you need to create a Comment and then create CommentRangeStart and CommentRangeEnd and set their identifiers to the same Id value.

CommentRangeStart is an inline-level node and can only be a child of Paragraph.

Examples
Shows how to create comments with replies and get all interested info.
public void CreateCommentsAndPrintAllInfo()
{
    Document doc = new Document();
    doc.RemoveAllChildren();

    Section sect = (Section)doc.AppendChild(new Section(doc));
    Body body = (Body)sect.AppendChild(new Body(doc));

    // Create a commented text with several comment replies
    for (int i = 0; i <= 10; i++)
    {
        Comment newComment = CreateComment(doc, "VDeryushev", "VD", DateTime.Now, "My test comment " + i);

        Paragraph para = (Paragraph)body.AppendChild(new Paragraph(doc));
        para.AppendChild(new CommentRangeStart(doc, newComment.Id));
        para.AppendChild(new Run(doc, "Commented text " + i));
        para.AppendChild(new CommentRangeEnd(doc, newComment.Id));
        para.AppendChild(newComment);

        for (int y = 0; y <= 2; y++)
        {
            newComment.AddReply("John Doe", "JD", DateTime.Now, "New reply " + y);
        }
    }

    // Look at information of our comments
    PrintAllCommentInfo(ExtractComments(doc));
}

/// <summary>
/// Create a new comment
/// </summary>
public static Comment CreateComment(Document doc, string author, string initials, DateTime dateTime, string text)
{
    Comment newComment = new Comment(doc)
    {
        Author = author, Initial = initials, DateTime = dateTime
    };
    newComment.SetText(text);

    return newComment;
}

/// <summary>
/// Extract comments from the document without replies
/// </summary>
public static List<Comment> ExtractComments(Document doc)
{
    List<Comment> collectedComments = new List<Comment>();

    NodeCollection comments = doc.GetChildNodes(NodeType.Comment, true);

    foreach (Comment comment in comments)
    {
        // All replies have ancestor, so we will add this check
        if (comment.Ancestor == null)
        {
            collectedComments.Add(comment);
        }
    }

    return collectedComments;
}

/// <summary>
/// Use an iterator and a visitor to print info of every comment from within a document.
/// </summary>
private static void PrintAllCommentInfo(List<Comment> comments)
{
    // Create an object that inherits from the DocumentVisitor class
    CommentInfoPrinter commentVisitor = new CommentInfoPrinter();

    // Get the enumerator from the document's comment collection and iterate over the comments
    using (IEnumerator<Comment> enumerator = comments.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            Comment currentComment = enumerator.Current;

            // Accept our DocumentVisitor it to print information about our comments
            if (currentComment != null)
            {
                // Get CommentRangeStart from our current comment and construct its information
                CommentRangeStart commentRangeStart = (CommentRangeStart)currentComment.PreviousSibling.PreviousSibling.PreviousSibling;
                commentRangeStart.Accept(commentVisitor);

                // Construct current comment information
                currentComment.Accept(commentVisitor);

                // Get CommentRangeEnd from our current comment and construct its information
                CommentRangeEnd commentRangeEnd = (CommentRangeEnd)currentComment.PreviousSibling;
                commentRangeEnd.Accept(commentVisitor);
            }
        }

        // Output of all information received
        Console.WriteLine(commentVisitor.GetText());
    }
}

/// <summary>
/// This Visitor implementation prints information about and contents of comments and comment ranges encountered in the document.
/// </summary>
public class CommentInfoPrinter : DocumentVisitor
{
    public CommentInfoPrinter()
    {
        mBuilder = new StringBuilder();
        mVisitorIsInsideComment = false;
    }

    /// <summary>
    /// Gets the plain text of the document that was accumulated by the visitor.
    /// </summary>
    public string GetText()
    {
        return mBuilder.ToString();
    }

    /// <summary>
    /// Called when a Run node is encountered in the document.
    /// </summary>
    public override VisitorAction VisitRun(Run run)
    {
        if (mVisitorIsInsideComment) IndentAndAppendLine("[Run] \"" + run.Text + "\"");

        return VisitorAction.Continue;
    }

    /// <summary>
    /// Called when a CommentRangeStart node is encountered in the document.
    /// </summary>
    public override VisitorAction VisitCommentRangeStart(CommentRangeStart commentRangeStart)
    {
        IndentAndAppendLine("[Comment range start] ID: " + commentRangeStart.Id);
        mDocTraversalDepth++;
        mVisitorIsInsideComment = true;

        return VisitorAction.Continue;
    }

    /// <summary>
    /// Called when a CommentRangeEnd node is encountered in the document.
    /// </summary>
    public override VisitorAction VisitCommentRangeEnd(CommentRangeEnd commentRangeEnd)
    {
        mDocTraversalDepth--;
        IndentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.Id + "\n");
        mVisitorIsInsideComment = false;

        return VisitorAction.Continue;
    }

    /// <summary>
    /// Called when a Comment node is encountered in the document.
    /// </summary>
    public override VisitorAction VisitCommentStart(Comment comment)
    {
        IndentAndAppendLine(string.Format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.Id,
            comment.Author, comment.DateTime));
        mDocTraversalDepth++;
        mVisitorIsInsideComment = true;

        return VisitorAction.Continue;
    }

    /// <summary>
    /// Called when the visiting of a Comment node is ended in the document.
    /// </summary>
    public override VisitorAction VisitCommentEnd(Comment comment)
    {
        mDocTraversalDepth--;
        IndentAndAppendLine("[Comment end]");
        mVisitorIsInsideComment = false;

        return VisitorAction.Continue;
    }

    /// <summary>
    /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
    /// </summary>
    /// <param name="text"></param>
    private void IndentAndAppendLine(string text)
    {
        for (int i = 0; i < mDocTraversalDepth; i++)
        {
            mBuilder.Append("|  ");
        }

        mBuilder.AppendLine(text);
    }

    private bool mVisitorIsInsideComment;
    private int mDocTraversalDepth;
    private readonly StringBuilder mBuilder;
}
See Also