# RadFlowDocumentEditor

Although `RadFlowDocument` can be created and modified by using the style properties and child collections of the document elements, this can be quite cumbersome. `RadFlowDocumentEditor` simplifies this process and achieves the same results with less code. It is also useful when several document elements must be inserted in the right order to ensure the document integrity—for example, when inserting fields, hyperlinks, images, and other elements.

* [Creating and Positioning](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/radflowdocumenteditor#creating-and-positioning)
* [Inserting Document Elements](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/radflowdocumenteditor#inserting-document-elements)
* [Changing Current Styles](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/radflowdocumenteditor#changing-current-styles)

## Creating and Positioning

`RadFlowDocumentEditor` is always associated with a single document, which it takes as a constructor parameter when it is created.

**Example 1: Create a RadFlowDocumentEditor for an existing document**

```C#
RadFlowDocument document = this.CreateDocument();
RadFlowDocumentEditor editor = new RadFlowDocumentEditor(document);
```

The editor maintains an internal position inside the document. This position points either inside a paragraph (to an inline) or directly after the end of a table element. The following methods are available for changing the position of the editor within a document:

* `MoveToInlineStart(InlineBase inline)`
* `MoveToInlineEnd(InlineBase inline)`
* `MoveToParagraphStart(Paragraph paragraph)`
* `MoveToParagraphEnd(Paragraph paragraph)`
* `MoveToTableEnd(Table table)`

The code from **Example 2** demonstrates how to position the editor after the second inline in the first paragraph of the document.

**Example 2: Move the editor after the second inline in the first paragraph**

```C#
Paragraph firstParagraph = document.EnumerateChildrenOfType<Paragraph>().First();
editor.MoveToInlineEnd(firstParagraph.Inlines[1]);
```

You can create a `RadFlowDocumentEditor` for an empty document (one with no sections). In this case, a section and a paragraph are automatically created when you call an insert method. **Example 3** creates a document with one section, containing one paragraph with the text "Hello word!".

**Example 3: Create an empty document and insert Hello word! text through the editor**

```C#
RadFlowDocumentEditor editor = new RadFlowDocumentEditor(new RadFlowDocument());
			editor.InsertText("Hello word!");
```

## Inserting Document Elements

Most of the insert methods of `RadFlowDocumentEditor` return the newly inserted element. This way you can set additional properties of the element if desired.

### Inserting Text

You can insert text [Runs](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/run) with the following methods:

| Method                    | Description                                                                                  |
| ------------------------- | -------------------------------------------------------------------------------------------- |
| `InsertText(string text)` | Inserts a new `Run` with the given text in the current paragraph.                            |
| `InsertLine(string text)` | Inserts a new `Run` with the given text in the current paragraph and starts a new paragraph. |

Both methods return the newly inserted `Run` element. If there are new lines in the text parameter, a new paragraph is also inserted for each new line. In this case, the returned run is the last one that is inserted.

The code in **Example 4** inserts a run containing a new line.

**Example 4: Insert text with a newline so the editor creates two lines**

```C#
editor.InsertText("First" + Environment.NewLine + "Second");
```

The result looks like **Figure 1** shows.

**Figure 1**
![Telerik RadWordsProcessing RadFlowDocumentEditor result showing two inserted lines labeled First and Second](https://www.telerik.com/document-processing-libraries/documentation/assets/04681070a6b62a68ecb55704f4d82cde/radwordsprocessing_editing_radflowdocumenteditor_01.png)

> The current [CharacterFormatting](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/radflowdocumenteditor#changing-current-styles) and [ParagraphFormatting](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/radflowdocumenteditor#changing-current-styles) is applied for each `Run` and `Paragraph` that is created.

### Inserting Paragraph

You can start a new [Paragraph](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/paragraph) with the `InsertParagraph()` method. The current `ParagraphFormatting` is applied to the new paragraph and the paragraph is returned.

**Example 5: Insert a second paragraph after writing the first paragraph text**

```C#
editor.InsertText("First paragraph");
editor.InsertParagraph();
editor.InsertText("Second paragraph");
```

**Figure 2** shows the result from **Example 5**.

**Figure 2: The Content Inserted in Example 5**
![Telerik RadWordsProcessing RadFlowDocumentEditor result showing two inserted paragraphs labeled First paragraph and Second paragraph](https://www.telerik.com/document-processing-libraries/documentation/assets/db324e6821ebb55cfedf77b55997b568/radwordsprocessing_editing_radflowdocumenteditor_02.png)

If you call the `InsertParagraph()` method while the editor is positioned in the middle of a paragraph, all the inlines after the position are moved inside the new paragraph. The effect is the same as pressing `Enter` while the cursor is in the middle of a paragraph in a text editor application.

### Inserting Sections

You can insert [Section](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/section) elements with the `InsertSection()` method. A paragraph with the new section's properties is added and the new `Section` element is returned.

**Example 6: Insert a new section at the current editor position**

```C#
editor.InsertSection();
```

> If you call the `InsertSection()` method while the editor is positioned in a `TableCell`, the `Table` is split at the current row. This means that if the table contains three rows, and the editor is positioned in a cell which is on the second row, the table is split into two tables—one with one row, which is added to the previous section, and one with two rows (containing the `TableCell` where the editor position was). The latter is added to the newly inserted `Section`.

### Inserting Hyperlinks

Hyperlinks in the `RadFlowDocument` model are [field elements described in the Fields article](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/concepts/fields/fields), which means they have code and result parts separated by [FieldCharacter](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/fieldcharacter) inlines. The `RadFlowDocumentEditor.InsertHyperlink()` method simplifies inserting hyperlinks:

```csharp
public Hyperlink InsertHyperlink(string text, string uri, bool isAnchor, string toolTip)
```

It automatically applies the "Hyperlink" built-in style to the inserted hyperlink if there is no explicitly set style in the `CharacterFormatting` options of the editor.

**Example 7: Insert a hyperlink to telerik.com with a tooltip**

```C#
editor.InsertHyperlink("telerik", "http://www.telerik.com", false, "Telerik site");
```

**Figure 3: Hyperlink**
![Telerik RadWordsProcessing RadFlowDocumentEditor hyperlink result showing a blue underlined telerik link with a Telerik site tooltip](https://www.telerik.com/document-processing-libraries/documentation/assets/c84546235e03b4c9aea6ba2892a30314/radwordsprocessing_editing_radflowdocumenteditor_03.png)

### Inserting Code Fields

You can insert fields with the `InsertField()` method, which accepts code and result fragments:

```csharp
public Field InsertField(string code, string result)
```

**Example 8** shows how to add page numbering in the header of a document:

**Example 8: Add PAGE and NUMPAGES fields to a document header for page numbering**

```C#
//Create header and move the editor
Header header = document.Sections[0].Headers.Add();
editor.MoveToParagraphStart(header.Blocks.AddParagraph());

editor.InsertText("Page ");
editor.InsertField("PAGE", "1");
editor.InsertText(" of ");
editor.InsertField("NUMPAGES", "1");
```

**Figure 4: The Page Numbering Inserted in Example 8**
![Telerik RadWordsProcessing RadFlowDocumentEditor page numbering result showing Page 3 of 5 centered in the document header](https://www.telerik.com/document-processing-libraries/documentation/assets/b0aea4efedd783e06c41eca29233cfa9/radwordsprocessing_editing_radflowdocumenteditor_04.png)

In this case the result is automatically updated when a document is opened in MS Word, because the page fields are in the header of the document.

> tip You can find an extensive list of field codes in the Office Open XML standard documentation - [ECMA-376](https://www.ecma-international.org/publications/standards/Ecma-376.htm) 4th edition, December 2012, Chapter 17.16.6 Field Definitions.

### Inserting Images

`RadFlowDocumentEditor` provides several methods for inserting [ImageInline](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/imageinline) and [FloatingImage](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/floatingimage). All of them return the inserted image element, so that you can perform additional manipulations.

* `InsertImageInline(ImageSource source, Size size)`
* `InsertImageInline(Stream stream, string extension, Size size)`
* `InsertFloatingImage(ImageSource source, Size size)`
* `InsertFloatingImage(Stream stream, string extension, Size size)`

**Example 9** shows how to insert an image using a stream:

**Example 9: Insert the Telerik logo as an inline image from a PNG stream**

```C#
editor.InsertText("Image:");
using (Stream stream = File.OpenRead("Telerik_logo.png"))
{
	editor.InsertImageInline(stream, "png", new Size(118, 28));
}
```

**Figure 5: The Image Inserted in Example 9**
![Telerik RadWordsProcessing RadFlowDocumentEditor image insertion result showing the text Image followed by the Telerik logo](https://www.telerik.com/document-processing-libraries/documentation/assets/ac80ce306b8ab4d8ad06a9072cf098dd/radwordsprocessing_editing_radflowdocumenteditor_05.png)

### Inserting Tables

Use the following methods to insert a [Table](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/table) in the document:

| Method                               | Description                                                    |
| ------------------------------------ | -------------------------------------------------------------- |
| `InsertTable()`                      | Inserts an empty table in the document.                        |
| `InsertTable(int rows, int columns)` | Inserts a table with the specified number of rows and columns. |

> The formatting specified with the [TableFormatting](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/radflowdocumenteditor#changing-current-styles) property is applied to the inserted table. After the insert operation the editor is automatically placed directly **after** the inserted table (not inside it).

The following example inserts a table with the "TableGrid" built-in style:

**Example 10: Apply the TableGrid style and insert a 2 by 4 table between surrounding text**

```C#
document.StyleRepository.AddBuiltInStyle(BuiltInStyleNames.TableGridStyleId);
editor.TableFormatting.StyleId = BuiltInStyleNames.TableGridStyleId;

editor.InsertText("Before table.");
editor.InsertTable(2, 4);
editor.InsertText("After table.");
```

**Figure 6: The Table in the Document**
![Telerik RadWordsProcessing RadFlowDocumentEditor table insertion result showing a small grid table between Before table and After table text](https://www.telerik.com/document-processing-libraries/documentation/assets/90498f6bfea1bcb3ec965afc878f0f58/radwordsprocessing_editing_radflowdocumenteditor_06.png)

> tip The `DocumentElementImporter` class allows you to import a document element from one document into another. For more information, refer to [Import Document Element](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/import-document-element).

## Changing Current Styles

When you use the insert methods of `RadFlowDocumentEditor`, the editor creates different document elements. You can control the formatting of the newly created elements with the following properties:

| Property              | Description                                                                                                                                                         |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CharacterFormatting` | Applied to all newly created `Run` elements. When inserting hyperlinks, the "Hyperlink" built-in style is applied only if no style is set in `CharacterFormatting`. |
| `ParagraphFormatting` | Applied to all newly created `Paragraph` elements, including paragraphs inserted through `InsertText()` and `InsertLine()`.                                         |
| `TableFormatting`     | Applied to all newly created `Table` elements.                                                                                                                      |

Formatting options are most useful when inserting multiple elements that must have consistent styling. For example, the code from **Example 11** inserts multiple paragraphs with no spacing between them and with text (`Run` elements) in "Consolas" font:

**Example 11: Apply Consolas font and zero paragraph spacing before inserting code-like lines**

```C#
//Set code block formatting
var codeFont = new ThemableFontFamily(new FontFamily("Consolas"));
editor.CharacterFormatting.FontFamily.LocalValue = codeFont;
editor.ParagraphFormatting.SpacingAfter.LocalValue = 0;

editor.InsertLine("static void Main(string[] args)");
editor.InsertLine("{");
editor.InsertLine("    Console.WriteLine(\"Hello World\");");
editor.InsertLine("}");
```

**Figure 7: The Content Inserted in Example 11**
![Telerik RadWordsProcessing RadFlowDocumentEditor styled content result showing a short Console.WriteLine code block formatted in Consolas](https://www.telerik.com/document-processing-libraries/documentation/assets/29c8e0faef9cd00881a6896655732c1d/radwordsprocessing_editing_radflowdocumenteditor_07.png)

## Deleting Content

**Example 12: Delete the content between the Start and End runs while keeping the boundary elements**

```C#
var document = new RadFlowDocument();
var editor = new RadFlowDocumentEditor(document);

editor.InsertParagraph();
var startRun = editor.InsertText("Start");
editor.InsertParagraph();
var middleRun = editor.InsertText("Middle");
editor.InsertParagraph();
var endRun = editor.InsertText("End");

editor.DeleteContent(startRun, endRun, false);
```

The method deletes everything between the "start" and "end" elements. You can choose if the "start" and "end" elements are deleted with the last parameter.

## See Also

* [RadFlowDocumentEditor API Reference](https://docs.telerik.com/devtools/document-processing/api/Telerik.Windows.Documents.Flow.Model.Editing.RadFlowDocumentEditor.html)
* [RadFlowDocument API Reference](https://docs.telerik.com/devtools/document-processing/api/Telerik.Windows.Documents.Flow.Model.RadFlowDocument.html)
* [Document Model](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/model/model)
* [Find and Replace](https://www.telerik.com/document-processing-libraries/documentation/libraries/radwordsprocessing/editing/find-and-replace/find-and-replace-text)
* [Inserting Formatted HTML Content in another RadFlowDocument using WordsProcessing](https://www.telerik.com/document-processing-libraries/documentation/knowledge-base/inserting-html-and-styling-radwordsprocessing)
