[Expand]General Information
[Expand]WinForms Controls
[Expand]ASP.NET Controls and MVC Extensions
[Expand]ASP.NET Bootstrap Controls
[Expand]ASP.NET Core Bootstrap Controls
[Collapse]WPF Controls
 [Expand]What's Installed
 [Expand]Common Concepts
 [Expand]MVVM Framework
 [Collapse]Controls and Libraries
  [Expand]Data Grid
  [Expand]Ribbon, Bars and Menu
  [Expand]Charts Suite
  [Expand]Pivot Grid
  [Collapse]Rich Text Editor
   [Expand]Product Information
    Product Class Structure
    Supported Formats
   [Expand]Getting Started
   [Expand]RichEditControl Document
    Text Formatting
    Import and Export
   [Expand]Page Layout
    Mail Merge
    Restrictions and Protection
    Syntax Highlighting
    Traversing the Document
   [Expand]Visual Elements
    HTML Tag Support
  [Expand]Tree List
  [Expand]Gauge Controls
  [Expand]Map Control
  [Expand]Layout Management
  [Expand]Windows Modern UI
  [Expand]Data Editors
  [Expand]Navigation Controls
  [Expand]Spell Checker
  [Expand]Property Grid
  [Expand]PDF Viewer
  [Expand]TreeMap Control
  [Expand]Diagram Control
  [Expand]Windows and Utility Controls
   Dialogs, Notifications and Panels
  [Expand]Scheduler (legacy)
 [Expand]Scaffolding Wizard
  Redistribution and Deployment
  Get More Help
 [Expand]API Reference
[Expand]Xamarin Controls
[Expand]Windows 10 App Controls
[Expand]Office File API
[Expand]Report and Dashboard Server
[Expand]eXpressApp Framework
[Expand]CodeRush Classic
[Expand]Cross-Platform Core Libraries
[Expand]Tools and Utilities
 End-User Documentation

Traversing the Document

This article details the techniques that can be used to navigate through the Rich Edit document to check the required information or perform certain actions with the document elements.

DXRichEdit provides means to navigate through a Document Model and Document Layout. Depending on the structure traversed, you can retrieve different information about the encountered elements. The Document Layout allows you to get only the location of the document elements, while navigating through the Document Model provides access to the properties and content of the retrieved entities.

Traversing technique is based on the Visitor and Iterator objects. The Iterator object moves through the document and obtains every element. The Visitor is used to perform operations when visiting an element of a specific type. With this Visitor-Iterator pattern, you can access all elements and perform actions on them using a single class. For details, refer to the Visitor pattern article.

Expanded Navigating the Document Model

Suppose you want to process the document text and display it in another text editing control (the MemoEdit in particular) in a way that the bold text is enclosed in asterisks and the rest of the text is shown without any formatting.

To accomplish this, do the following:

  1. Declare an abstract class that descends from the DocumentVisitorBase class. This class implements the IDocumentVisitor interface, which provides the necessary Visit methods that take all possible document element types as parameters.

    Use the class constructor to initialize a new instance of the System.Text.StringBuilder class, which will store the text processed by the Visitor. Override the corresponding IDocumentVisitor.Visit method as shown on the code sample below to perform the required actions when visiting a specific DocumentText element.

    Show Me

    A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=T384347.

    MyVisitor is a DocumentVisitorBase class descendant which provides a method that processes DocumentText elements to do the following.
    • Enclose the bold text in asterisks
    • Return all characters without formatting
    • Replace the paragraph ends with newline symbols
    Other document elements are skipped.

  2. Important

    You can only browse and modify the existing content of the visited elements. Adding or removing the content is not permitted.

  3. Create a new object of the Visitor class.

  4. Create an Iterator object, represented by the DocumentIterator class.

  5. Call the DocumentIterator.MoveNext method to loop the iterator through all the document elements until it returns false, i.e., until the iterator has reached the end of the document. This loop can be used to provide the Visitor with access to the document entities, so that it can perform operations, declared in the Visit method earlier. To do that, call the IDocumentElement.Accept method to the current document element (the DocumentIterator.Current property). As a result, the Visitor will execute the related Visit method for every iterated element.

  6. Tip

    It is also possible to check the elements of a specific type only. To do that, pass this element type as a parameter to the DocumentIterator.MoveNext method.

  7. Write the processed text stored in the Text property to the Memo Edit control.

As a result, the text will be converted as illustrated below.

When obtaining an element, the Iterator returns the information about it as read-only sub-properties of an object returned by the use the DocumentIterator.Current property.

By default, the Iterator obtains textual elements containing hidden characters. The element's ReadOnlyTextPropertiesBase.Hidden property indicates whether the iterated entity contains them. To make the iterator skip hidden text, pass true to the Iterator constructor as the visibleTextOnly parameter. As for the non-textual elements, the iterator obtains all of them, regardless of their visibility.

Some elements, such as DocumentTextBox or DocumentCommentElement, can contain other elements. To get the content of these entities, create a new visitor and iterator instance in the corresponding Visit method. Use DocumentTextBox.GetIterator or DocumentCommentElement.GetIterator method to provide a new iterator with access to the element content. To skip the hidden content contained in obtained elements, pass true as the method's visibleTextOnly parameter.


The iterator obtains the elements that are located in the main body of the document model. The header or footer entities are not accessible to it.

Expanded Navigating the Document Layout

The document layout can be traversed with the use of the Visitor and Iterator as well, but here, these two instances operate separately.

Traversing the document layout using the Visitor (a LayoutVisitor object) allows you to perform required actions while visiting a specific element. The Visitor operates with the same algorithm as described above, but with one difference: in response to the visitor's LayoutVisitor.Visit method, the Accept method is called by the LayoutElement itself, not by the Iterator. To get detailed information about Visitor implementation, refer to the Layout API article.

Navigating the document using the Iterator (a LayoutIterator object) allows you to iterate through every LayoutElement element and obtain its properties. The Iterator can move both backwards and forwards with the use of the DocumentIterator.MoveNext and LayoutIterator.MovePrevious methods. All obtained element characteristics, such as LayoutElement.Type, LayoutElement.Bounds and LayoutElement.Parent, are accessible through the LayoutIterator.Current property. Since the Visit methods are not provided, it is impossible to define an operation when visiting the element.

Apart from the LayoutVisitor traversing the elements directly, the LayoutIterator navigates through the levels of the DocumentLayout object, from LayoutLevel.Page to LayoutLevel.Box, and gets the elements related to the current level. You can traverse only a specific level by passing the required LayoutLevel value as the method parameter. Setting the method's allowTreeTraversal argument to true makes the Iterator start from a specified level and move further.

Show Me

A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=T274525.

This code snippet calls different LayoutIterator.MoveNext overloads to illustrate different techniques of tree navigation. Checking the LayoutIterator.IsLayoutValid value is required because the user can modify the document layout in the meantime.

The LayoutIterator.IsStart and LayoutIterator.IsEnd properties indicate whether the iterator reached the start or end of the range for which it has been created, respectively.

Expanded See Also

Is this topic helpful?​​​​​​​