New to Telerik UI for WinForms? Download free 30-day trial

Bookmarks

Bookmarks are a powerful tool for marking parts of the document, which can be later retrieved and reviewed. They can be added to the document both programmatically and via the UI. You can also have hyperlinks pointing to the annotations in the document. This is very convenient, as it provides the means for easier navigation in the document and enables features like table of contents.

Adding Bookmarks via the UI

Bookmarks can be inserted in the document and removed through the ManageBookmarksDialog, which is opened on pressing the Bookmark button in the Insert tab of the default RadRichTextEditorRibbonUI.

WinForms RadRichTextEditor Adding Bookmarks

As all pop-ups that RadRichTextEditor uses, the ManageBookmarksDialog can be completely replaced by another, user-defined dialog implementing an interface.

Using Bookmarks Programmatically

The document elements that encapsulate the bookmarks functionality are BookmarkRangeStart and BookMarkRangeEnd, which are placed at the start and the end of the bookmark respectively. Some of the useful methods that RadRichTextEditor and RadDocument expose are:

  • InsertBookmark(string bookmarkName) – inserts a bookmark with the name specified. If there is selection in the document, the BookmarkRangeStart will be inserted just before the first selected element and the BookmarkRangeEnd will be added at the end of the first selection range.

  • Document.GoToBookmark(string bookmarkName) / Document.GoToBookmark(BookmarkRangeStart bookmarkStart): Both methods move the caret to the bookmark specified. As bookmarks with the same name cannot be inserted in the same document, the name of the bookmark can be used as an identifier.

  • Document.Selection.SelectAnnotationRange(AnnotationRangeStart annotationStart) – selects the annotation passed as parameter. Particularly useful, as most methods of RadRichTextEditor and RadDocument operate on the selection. For example, if you invoke Delete(false), the text of the bookmark along with the bookmark itself will be erased.

  • DeleteBookmark(string bookmarkName) / DeleteBookmark(BookmarkRangeStart bookmarkRangeStart): These two methods remove the bookmark. The text in the document between the BookmarkRangeStart and BookmarkRangeEnd is not deleted.

  • Document.GetAllBookmarks() – returns an IEnumerable containing all BookmarkRangeStarts.

  • Document.EnumerateChildrenOfType<BookmarkRangeStart>() – returns all bookmarks in the document. This method can be used on document elements other than RadDocument, in case you want to detect all bookmarks in a limited part of the document, e.g. a Paragraph or a Table.

You can also add bookmarks in a document you are creating manually. As both BookmarkRangeStart and BookMarkRangeEnd inherit from Inline, they can be added to the Inlines property of a Paragraph, just like any other Inline. You can also have document positions go to the start or end of the bookmark and perform non-standard operations.

private void GenerateBookmarksDocument()
{
    RadDocument document = new RadDocument();

    Section bmSection = new Section();
    Paragraph bmParagraph = new Paragraph();
    Span bmSpan = new Span("Content prior bookmark[");
    Span bmSpan2 = new Span("]Content after bookmark");
    Span bmContent = new Span("Content in Bookmark");

    BookmarkRangeEnd bmRangeEnd = new BookmarkRangeEnd();
    BookmarkRangeStart bmRangeStart = (BookmarkRangeStart)bmRangeEnd.CreatePairedStart();
    bmRangeStart.Name = System.Guid.NewGuid().ToString();

    bmParagraph.Inlines.Add(bmSpan);
    bmParagraph.Inlines.Add(bmRangeStart);
    bmParagraph.Inlines.Add(bmContent);
    bmParagraph.Inlines.Add(bmRangeEnd);
    bmParagraph.Inlines.Add(bmSpan2);

    bmSection.Blocks.Add(bmParagraph);
    document.Sections.Add(bmSection);

    this.radRichTextEditor1.Document = document;
}

Private Sub GenerateBookmarksDocument()
    Dim document As New RadDocument()
    Dim bmSection As New Section()
    Dim bmParagraph As New Paragraph()
    Dim bmSpan As New Span("Content prior bookmark[")
    Dim bmSpan2 As New Span("]Content after bookmark")
    Dim bmContent As New Span("Content in Bookmark")
    Dim bmRangeEnd As New BookmarkRangeEnd()
    Dim bmRangeStart = DirectCast(bmRangeEnd.CreatePairedStart(), BookmarkRangeStart)
    bmRangeStart.Name = System.Guid.NewGuid().ToString()
    bmParagraph.Inlines.Add(bmSpan)
    bmParagraph.Inlines.Add(bmRangeStart)
    bmParagraph.Inlines.Add(bmContent)
    bmParagraph.Inlines.Add(bmRangeEnd)
    bmParagraph.Inlines.Add(bmSpan2)
    bmSection.Blocks.Add(bmParagraph)
    document.Sections.Add(bmSection)
    Me.radRichTextEditor1.Document = document
End Sub

For example, you can keep a Dictionary mapping each bookmark name to another string and substitute a bookmark with the corresponding text using the following method:

private void ReplaceContentOfBookmark(string bookmarkName)
{
    BookmarkRangeStart bookmark = this.radRichTextEditor1.Document.GetBookmarkByName(bookmarkName);
    this.radRichTextEditor1.Document.Selection.SelectAnnotationRange(bookmark);
    this.radRichTextEditor1.Document.Delete(false);
    this.radRichTextEditor1.Insert("new text");
}

Private Sub ReplaceContentOfBookmark(ByVal bookmarkName As String)
    Dim bookmark As BookmarkRangeStart = Me.radRichTextEditor1.Document.GetBookmarkByName(bookmarkName)
    Me.radRichTextEditor1.Document.Selection.SelectAnnotationRange(bookmark)
    Me.radRichTextEditor1.Document.Delete(False)
    Me.radRichTextEditor1.Insert("new text")
End Sub

If you want to preserve the bookmarks in the document and only change the text between the BookmarkRangeStart and BookmarkRangeEnd document elements, you can do so like this:


private void ChangeAllBookmarks(RadRichTextEditor radRichTextEditor)
{
    BookmarkRangeStart[] bookmarks = radRichTextEditor.Document.GetAllBookmarks().ToArray<BookmarkRangeStart>();
    DocumentPosition start = new DocumentPosition(radRichTextEditor.Document);
    DocumentPosition end = new DocumentPosition(radRichTextEditor.Document);
    foreach (BookmarkRangeStart item in bookmarks)
    {
        radRichTextEditor.Document.GoToBookmark(item);

        start.MoveToInline(item.FirstLayoutBox as InlineLayoutBox, 0);
        end.MoveToInline(item.End.FirstLayoutBox as InlineLayoutBox, 0);
        start.MoveToNextInline();
        radRichTextEditor.Document.Selection.SetSelectionStart(start);
        radRichTextEditor.Document.Selection.AddSelectionEnd(end);

        radRichTextEditor.Delete(false);

        radRichTextEditor.Insert("new text");
    }
}

Private Sub ChangeAllBookmarks(ByVal radRichTextEditor As RadRichTextEditor)
    Dim bookmarks() As BookmarkRangeStart = radRichTextEditor.Document.GetAllBookmarks().ToArray()
    Dim start As New DocumentPosition(radRichTextEditor.Document)
    Dim [end] As New DocumentPosition(radRichTextEditor.Document)
    For Each item As BookmarkRangeStart In bookmarks
        radRichTextEditor.Document.GoToBookmark(item)
        start.MoveToInline(TryCast(item.FirstLayoutBox, InlineLayoutBox), 0)
        [end].MoveToInline(TryCast(item.End.FirstLayoutBox, InlineLayoutBox), 0)
        start.MoveToNextInline()
        radRichTextEditor.Document.Selection.SetSelectionStart(start)
        radRichTextEditor.Document.Selection.AddSelectionEnd([end])
        radRichTextEditor.Delete(False)
        radRichTextEditor.Insert("new text")
    Next item
End Sub

In this article