Skip to main content

Document Management in Blazor Rich Text Editor

  • 7 minutes to read

This section contains examples that demonstrate how to create, open, save, print, and export documents in the Rich Text Editor.

Document Formats

The Rich Text Editor supports the following document formats:

  • Office Open XML Document (DOCX)
  • Rich Text Format (RTF)
  • Plain Text (TXT)

You can use the DevExpress Office File API library or a third-party server library to convert a document to other formats.

View Example: How to export a document to a file (HTML format)

Create a Document

Call the NewDocumentAsync(CancellationToken) method to create a new document:

<DxRichEdit @ref="@richEdit" />

@code {
    DxRichEdit richEdit { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
        @* ... *@
            await richEdit.NewDocumentAsync();
            @* ... *@
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}

Open a Document

Use one of the following methods to open a document:

Assign Document Content

Assign a document as a byte array to the DocumentContent property and the document’s format value to the DocumentFormat property to open this document in the Rich Text Editor. If you do not set the DocumentFormat property before you open a document, the Rich Text Editor cannot parse the document correctly.

<DxRichEdit DocumentFormat="DocumentFormat.Rtf" @bind-DocumentContent="@documentContent" />

@code {
    byte[] documentContent;
    string filePath = "C:\\Users\\Public\\annual-report.rtf";

    protected override async Task OnInitializedAsync() {
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
            documentContent = await File.ReadAllBytesAsync(filePath);
            await base.OnInitializedAsync();
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
    }
}

The Rich Text Editor updates the DocumentContent property value in the following cases:

Handle the DocumentContentChanged event to save changes to a file.

View Example: How to use the Rich Text Editor inside an EditForm

Load a Document

Call a LoadDocumentAsync method overload to load a document.

Load a Document from a Byte Array

Call the LoadDocumentAsync(Byte[], DocumentFormat, CancellationToken) method to load a document in a specified format from a byte array:

<DxRichEdit @ref="@richEdit" />

@code {
    DxRichEdit richEdit { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
        @* ... *@
            byte[] fileContent = Convert.FromBase64String("e1xydGYxXGRlZmYwe1xmb250dGJse1xmMCBDYWxpYnJpO319e1xjb2xvcnRibCA7XHJlZDBcZ3JlZW4wXGJsdWUyNTUgO1xyZWQyNTVcZ3JlZW4yNTVcYmx1ZTI1NSA7fXtcKlxkZWZjaHAgXGZzMjJ9e1xzdHlsZXNoZWV0IHtccWxcZnMyMiBOb3JtYWw7fXtcKlxjczFcZnMyMiBEZWZhdWx0IFBhcmFncmFwaCBGb250O317XCpcY3MyXGZzMjJcY2YxIEh5cGVybGluazt9e1wqXHRzM1x0c3Jvd2RcZnMyMlxxbFx0c3ZlcnRhbHRcdHNjZWxsY2JwYXQyXHRzY2VsbHBjdDBcY2x0eGxydGIgTm9ybWFsIFRhYmxlO319e1wqXGxpc3RvdmVycmlkZXRhYmxlfXtcaW5mb31cbm91aWNvbXBhdFxzcGx5dHduaW5lXGh0bWF1dHNwXGV4cHNocnRuXHNwbHRwZ3BhclxkZWZ0YWI3MjBcc2VjdGRcbWFyZ2xzeG4xNDQwXG1hcmdyc3huMTQ0MFxtYXJndHN4bjE0NDBcbWFyZ2JzeG4xNDQwXGhlYWRlcnk3MjBcZm9vdGVyeTcyMFxwZ3dzeG4xMjI0MFxwZ2hzeG4xNTg0MFxjb2xzMVxjb2xzeDcyMFxwYXJkXHBsYWluXHFse1xmczIyXGNmMFxjczEgRG9jdW1lbnQgdGV4dH1cZnMyMlxjZjBccGFyfQ==");
            richEdit.LoadDocumentAsync(fileContent, DocumentFormat.Rtf);
            @* ... *@
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}

Load a Document from a File

Call the LoadDocumentAsync(String, CancellationToken) method to load a document from a specified file path. The Rich Text Editor automatically detects the document’s format. Override the Detect(String) method to implement your own format detection logic.

<DxRichEdit @ref="@richEdit" />

@code {
    DxRichEdit richEdit { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
        @* ... *@
            await richEdit.LoadDocumentAsync("C:\\Users\\Public\\annual-report.docx");
            @* ... *@
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}

Call the LoadDocumentAsync(String, DocumentFormat, CancellationToken) method and pass the document format as a parameter to omit automatic detection and improve performance.

Load a Document from a Stream

Call the LoadDocumentAsync(Stream, CancellationToken) method to load a document from a specified stream. The Rich Text Editor automatically detects the document’s format. Override the Detect(Stream) method to implement your own file format detection logic.

<DxRichEdit @ref="@richEdit" />

@code {
    DxRichEdit richEdit { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
        @* ... *@
            var fileStream = new FileStream("C:\\Users\\Public\\annual-report.docx", FileMode.Open);
            await richEdit.LoadDocumentAsync(fileStream);
            @* ... *@
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}

Call the LoadDocumentAsync(Stream, DocumentFormat, CancellationToken) method and pass the document format as a parameter to omit automatic detection and improve performance.

Save a Document

Handle the DocumentContentChanged event to enable save operations in the Rich Text Editor. Otherwise, the FileSave ribbon command is hidden, the SaveDocumentAsync(CancellationToken) method has no effect, and the auto-save feature is disabled.

Call the SaveDocumentAsync(CancellationToken) method to raise the DocumentContentChanged event and save changes. The Modified property specifies whether an open document has unsaved changes.

<DxRichEdit @ref="@richEdit" DocumentContent="@documentContent" DocumentFormat="@format"
    DocumentContentChanged="OnDocumentContentChanged" />

@code {
    byte[] documentContent;
    DxRichEdit richEdit;
    DocumentFormat format = DocumentFormat.Rtf;
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
            if (richEdit.Modified)
                await richEdit.SaveDocumentAsync();
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
        @* ... *@
    async Task OnDocumentContentChanged(byte[] content) {
        try {
            documentContent = content;
            await File.WriteAllBytesAsync("C:\\Users\\Public\\annual-report.rtf", documentContent);
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
    }   
}

The DocumentContentChanging event occurs before the DocumentContentChanged event. Handle the DocumentContentChanging event to notify users that the Rich Text Editor starts saving.

View Example: How to implement custom document save capabilities

Enable Auto-Save Feature

Assign a timeout value to the AutoSaveTimeout property to raise the DocumentContentChanged event each time this timeout expires:

<DxRichEdit @ref="@richEdit" AutoSaveTimeout="TimeSpan.FromMinutes(2)"
    DocumentContent="@documentContent" DocumentContentChanged="OnDocumentContentChanged" />

@code {
    byte[] documentContent;
    DxRichEdit richEdit;

    async Task OnDocumentContentChanged(byte[] content) {
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
            documentContent = content;
            await richEdit.ExportDocumentAsync("C:\\Users\\Public\\annual-report.rtf", DocumentFormat.Rtf);
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
    }
}

Call the PrintDocumentAsync method to open the browser’s Print dialog:

<DxRichEdit @ref="@richEdit" />

@code {
    DxRichEdit richEdit { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
        @* ... *@
            await richEdit.PrintDocumentAsync();
            @* ... *@
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}

Export a Document

Call an ExportDocumentAsync method overload to export an open document.

Export to a Byte Array

Call the ExportDocumentAsync(DocumentFormat, CancellationToken) method to export the document to a byte array in a specified format:

<DxRichEdit @ref="richEdit1" />
<DxRichEdit @ref="richEdit2" />
@code {
    DxRichEdit richEdit1 { get; set; }
    DxRichEdit richEdit2 { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
            byte[] fileContent = await richEdit1.ExportDocumentAsync(DocumentFormat.Rtf);
            await richEdit2.LoadDocumentAsync(fileContent, DocumentFormat.Rtf);
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}

Export to a File

Call the ExportDocumentAsync(String, DocumentFormat, CancellationToken) method to export the document to a file in a specified format:

<DxRichEdit @ref="@richEdit" />

@code {
    DxRichEdit richEdit { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
        @* ... *@
            await richEdit.ExportDocumentAsync("C:\\Users\\Public\\annual-report.rtf", DocumentFormat.Rtf);
            @* ... *@
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}

Export to a Stream

Call the ExportDocumentAsync(Stream, DocumentFormat, CancellationToken) method to export the document to a stream in a specified format:

<DxRichEdit @ref="@richEdit" />

@code {
    DxRichEdit richEdit { get; set; }
    @* ... *@
    /* Surround the code that contains an asynchronous operation with a try-catch block to handle
    the OperationCanceledException. This exception is thrown when an asynchronous operation is canceled. */
        try {
        @* ... *@
            using (MemoryStream memoryStream = new MemoryStream()) {
                await richEdit.ExportDocumentAsync(memoryStream, DocumentFormat.Rtf);
                // ...
            }
            @* ... *@
        }
        catch (OperationCanceledException e) {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
}