GemBox.Document is a .NET component that enables you to read, write, edit, convert, and print document files from your .NET applications using one simple API.

Word Editor in WPF

Following example shows interoperability between GemBox.Document component and WPF RichTextBox control via RTF format.

Sample also implements common rich text editor functionalities and shows how to copy and paste between clipboard and GemBox.Document.

Visual Studio solution can be downloaded from: WpfRichTextEditor.zip.

Screenshot
RichTextBox / Clipboard Screenshot

See the full code below.

<Window x:Class="WpfRichTextEditor.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Rich Text Editor" WindowState="Maximized">

    <DockPanel>

        <ToolBarTray DockPanel.Dock="Top">

            <ToolBarTray.Resources>
                <Style TargetType="Image">
                    <Style.Triggers>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" Value="0.5"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Width" Value="30"/>
                    <Setter Property="TextAlignment" Value="Center"/>
                    <Setter Property="FontFamily" Value="Palatino Linotype"/>
                    <Setter Property="FontSize" Value ="14"/>
                    <Setter Property="FontWeight" Value="Bold"/>
                </Style>
            </ToolBarTray.Resources>
            
            <ToolBar Header="GemBox ToolBar" ToolTip="Commands in this group use GemBox.Document component">
                <ToolBar.CommandBindings>
                    <CommandBinding Command="Open" Executed="Open"/>
                    <CommandBinding Command="Save" Executed="Save" CanExecute="CanSave" />
                    <CommandBinding Command="SaveAs" Executed="Save" CanExecute="CanSave" />
                    <CommandBinding Command="Cut" Executed="Cut" CanExecute="CanCut" />
                    <CommandBinding Command="Copy" Executed="Copy" CanExecute="CanCopy" />
                    <CommandBinding Command="Paste" Executed="Paste" CanExecute="CanPaste"/>
                </ToolBar.CommandBindings>
                <Button Command="Open" ToolTip="Open">
                    <Image Source="Icons/Open.png"/>
                </Button>
                <Button Command="Save" ToolTip="Save">
                    <Image Source="Icons/Save.png"/>
                </Button>
                <Separator/>
                <Button Command="Cut" ToolTip="Cut with GemBox.Document">
                    <Image Source="Icons/Cut.png"/>
                </Button>
                <Button Command="Copy" ToolTip="Copy with GemBox.document">
                    <Image Source="Icons/Copy.png"/>
                </Button>
                <Button Command="Paste" CommandParameter="prepend" ToolTip="Paste prepend with GemBox.Document">
                    <Image Source="Icons/Paste.png"/>
                </Button>
                <Button Command="Paste" CommandParameter="append" ToolTip="Paste append with GemBox.Document">
                    <Image Source="Icons/Paste.png"/>
                </Button>
            </ToolBar>

            <ToolBar Header="WPF ToolBar" ToolTip="Commands in this group use only WPF">
                <Button Command="Undo" ToolTip="Undo">
                    <Image Source="Icons/Undo.png"/>
                </Button>
                <Button Command="Redo" ToolTip="Redo">
                    <Image Source="Icons/Redo.png"/>
                </Button>
                <Separator/>
                <Button Command="Cut" ToolTip="Cut">
                    <Image Source="Icons/Cut.png"/>
                </Button>
                <Button Command="Copy" ToolTip="Copy">
                    <Image Source="Icons/Copy.png"/>
                </Button>
                <Button Command="Paste" ToolTip="Paste">
                    <Image Source="Icons/Paste.png"/>
                </Button>
                <Separator/>
                <Button Command="ToggleBold" ToolTip="Bold">
                    <TextBlock Text="B" FontWeight="Bold"/>
                </Button>
                <Button Command="ToggleItalic" ToolTip="Italic">
                    <TextBlock Text="I" FontStyle="Italic"/>
                </Button>
                <Button Command="ToggleUnderline" ToolTip="Underline">
                    <TextBlock Text="U" TextDecorations="Underline"/>
                </Button>
                <Separator/>
                <Button Command="IncreaseFontSize" ToolTip="Increase Font Size">
                    <Image Source="Icons/IncreaseFontSize.png"/>
                </Button>
                <Button Command="DecreaseFontSize" ToolTip="Decrease Font Size">
                    <Image Source="Icons/DecreaseFontSize.png"/>
                </Button>
                <Separator/>
                <Button Command="ToggleBullets" ToolTip="Bullets">
                    <Image Source="Icons/ToggleBullets.png"/>
                </Button>
                <Button Command="ToggleNumbering" ToolTip="Numbering">
                    <Image Source="Icons/ToggleNumbering.png"/>
                </Button>
                <Separator/>
                <Button Command="DecreaseIndentation" ToolTip="Decrease Indentation">
                    <Image Source="Icons/DecreaseIndentation.png"/>
                </Button>
                <Button Command="IncreaseIndentation" ToolTip="Increase Indentation">
                    <Image Source="Icons/IncreaseIndentation.png"/>
                </Button>
                <Separator/>
                <Button Command="AlignLeft" ToolTip="Align Left">
                    <Image Source="Icons/AlignLeft.png"/>
                </Button>
                <Button Command="AlignCenter" ToolTip="Align Center">
                    <Image Source="Icons/AlignCenter.png"/>
                </Button>
                <Button Command="AlignRight" ToolTip="Align Right">
                    <Image Source="Icons/AlignRight.png"/>
                </Button>
                <Button Command="AlignJustify" ToolTip="Align Justify">
                    <Image Source="Icons/AlignJustify.png"/>
                </Button>
            </ToolBar>

        </ToolBarTray>

        <RichTextBox x:Name="richTextBox" AcceptsTab="True" VerticalScrollBarVisibility="Auto"/>

    </DockPanel>

</Window>
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using GemBox.Document;
using Microsoft.Win32;

namespace WpfRichTextEditor
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        }

        private void Open(object sender, ExecutedRoutedEventArgs e)
        {
            var dialog = new OpenFileDialog()
            {
                AddExtension = true,
                Filter =
                    "All Documents (*.docx;*.docm;*.doc;*.dotx;*.dotm;*.dot;*.htm;*.html;*.rtf;*.txt)|*.docx;*.docm;*.dotx;*.dotm;*.doc;*.dot;*.htm;*.html;*.rtf;*.txt|" +
                    "Word Documents (*.docx)|*.docx|" +
                    "Word Macro-Enabled Documents (*.docm)|*.docm|" +
                    "Word 97-2003 Documents (*.doc)|*.doc|" +
                    "Word Templates (*.dotx)|*.dotx|" +
                    "Word Macro-Enabled Templates (*.dotm)|*.dotm|" +
                    "Word 97-2003 Templates (*.dot)|*.dot|" +
                    "Web Pages (*.htm;*.html)|*.htm;*.html|" +
                    "Rich Text Format (*.rtf)|*.rtf|" +
                    "Text Files (*.txt)|*.txt"
            };

            if (dialog.ShowDialog() == true)
                using (var stream = new MemoryStream())
                {
                    // Convert input file to RTF stream.
                    DocumentModel.Load(dialog.FileName).Save(stream, SaveOptions.RtfDefault);

                    stream.Position = 0;

                    // Load RTF stream into RichTextBox.
                    var textRange = new TextRange(this.richTextBox.Document.ContentStart, this.richTextBox.Document.ContentEnd);
                    textRange.Load(stream, DataFormats.Rtf);
                }
        }

        private void Save(object sender, ExecutedRoutedEventArgs e)
        {
            var dialog = new SaveFileDialog()
            {
                AddExtension = true,
                Filter =
                    "Word Document (*.docx)|*.docx|" +
                    "Word Macro-Enabled Document (*.docm)|*.docm|" +
                    "Word Template (*.dotx)|*.dotx|" +
                    "Word Macro-Enabled Template (*.dotm)|*.dotm|" +
                    "PDF (*.pdf)|*.pdf|" +
                    "XPS Document (*.xps)|*.xps|" +
                    "Web Page (*.htm;*.html)|*.htm;*.html|" +
                    "Single File Web Page (*.mht;*.mhtml)|*.mht;*.mhtml|" +
                    "Rich Text Format (*.rtf)|*.rtf|" +
                    "Plain Text (*.txt)|*.txt|" +
                    "Image (*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.tif;*.tiff;*.wdp)|*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.tif;*.tiff;*.wdp"
            };

            if (dialog.ShowDialog(this) == true)
                using (var stream = new MemoryStream())
                {
                    // Save RichTextBox content to RTF stream.
                    var textRange = new TextRange(this.richTextBox.Document.ContentStart, this.richTextBox.Document.ContentEnd);
                    textRange.Save(stream, DataFormats.Rtf);

                    stream.Position = 0;

                    // Convert RTF stream to output format.
                    DocumentModel.Load(stream, LoadOptions.RtfDefault).Save(dialog.FileName);
                    Process.Start(dialog.FileName);
                }
        }

        private void Cut(object sender, ExecutedRoutedEventArgs e)
        {
            this.Copy(sender, e);

            // Clear selection.
            this.richTextBox.Selection.Text = string.Empty;
        }

        private void Copy(object sender, ExecutedRoutedEventArgs e)
        {
            using (var stream = new MemoryStream())
            {
                // Save RichTextBox selection to RTF stream.
                this.richTextBox.Selection.Save(stream, DataFormats.Rtf);

                stream.Position = 0;

                // Save RTF stream to clipboard.
                DocumentModel.Load(stream, LoadOptions.RtfDefault).Content.SaveToClipboard();
            }
        }

        private void Paste(object sender, ExecutedRoutedEventArgs e)
        {
            using (var stream = new MemoryStream())
            {
                // Save RichTextBox content to RTF stream.
                var textRange = new TextRange(this.richTextBox.Document.ContentStart, this.richTextBox.Document.ContentEnd);
                textRange.Save(stream, DataFormats.Rtf);

                stream.Position = 0;

                // Load document from RTF stream and prepend or append clipboard content to it.
                var document = DocumentModel.Load(stream, LoadOptions.RtfDefault);
                var position = (string)e.Parameter == "prepend" ? document.Content.Start : document.Content.End;
                position.LoadFromClipboard();

                stream.Position = 0;

                // Save document to RTF stream.
                document.Save(stream, SaveOptions.RtfDefault);

                stream.Position = 0;

                // Load RTF stream into RichTextBox.
                textRange.Load(stream, DataFormats.Rtf);
            }
        }

        private void CanSave(object sender, CanExecuteRoutedEventArgs e)
        {
            if (this.richTextBox != null)
            {
                var document = this.richTextBox.Document;
                var startPosition = document.ContentStart.GetNextInsertionPosition(LogicalDirection.Forward);
                var endPosition = document.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
                e.CanExecute = startPosition != null && endPosition != null && startPosition.CompareTo(endPosition) < 0;
            }
            else
                e.CanExecute = false;
        }

        private void CanCut(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.richTextBox != null && !this.richTextBox.Selection.IsEmpty;
        }

        private void CanCopy(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.richTextBox != null && !this.richTextBox.Selection.IsEmpty;
        }

        private void CanPaste(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.richTextBox != null && this.richTextBox.IsKeyboardFocused;
        }
    }
}
Imports System.Diagnostics
Imports System.IO
Imports System.Windows
Imports System.Windows.Documents
Imports System.Windows.Input
Imports GemBox.Document
Imports Microsoft.Win32

Namespace WpfRichTextEditor

    Partial Public Class MainWindow
        Inherits Window

        Public Sub New()

            InitializeComponent()

            ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        End Sub

        Private Sub Open(sender As Object, e As ExecutedRoutedEventArgs)

            Dim dialog = New OpenFileDialog() With {
                .AddExtension = True,
                .Filter =
                    "All Documents (*.docx;*.docm;*.doc;*.dotx;*.dotm;*.dot;*.htm;*.html;*.rtf;*.txt)|*.docx;*.docm;*.dotx;*.dotm;*.doc;*.dot;*.htm;*.html;*.rtf;*.txt|" +
                    "Word Documents (*.docx)|*.docx|" +
                    "Word Macro-Enabled Documents (*.docm)|*.docm|" +
                    "Word 97-2003 Documents (*.doc)|*.doc|" +
                    "Word Templates (*.dotx)|*.dotx|" +
                    "Word Macro-Enabled Templates (*.dotm)|*.dotm|" +
                    "Word 97-2003 Templates (*.dot)|*.dot|" +
                    "Web Pages (*.htm;*.html)|*.htm;*.html|" +
                    "Rich Text Format (*.rtf)|*.rtf|" +
                    "Text Files (*.txt)|*.txt"
            }

            If dialog.ShowDialog() = True Then
                Using stream = New MemoryStream()

                    ' Convert input file to RTF stream.
                    DocumentModel.Load(dialog.FileName).Save(stream, SaveOptions.RtfDefault)

                    stream.Position = 0

                    ' Load RTF stream into RichTextBox.
                    Dim textRange = New TextRange(Me.richTextBox.Document.ContentStart, Me.richTextBox.Document.ContentEnd)
                    textRange.Load(stream, DataFormats.Rtf)

                End Using
            End If

        End Sub

        Private Sub Save(sender As Object, e As ExecutedRoutedEventArgs)

            Dim dialog = New SaveFileDialog() With {
                .AddExtension = True,
                .Filter =
                    "Word Document (*.docx)|*.docx|" +
                    "Word Macro-Enabled Document (*.docm)|*.docm|" +
                    "Word Template (*.dotx)|*.dotx|" +
                    "Word Macro-Enabled Template (*.dotm)|*.dotm|" +
                    "PDF (*.pdf)|*.pdf|" +
                    "XPS Document (*.xps)|*.xps|" +
                    "Web Page (*.htm;*.html)|*.htm;*.html|" +
                    "Single File Web Page (*.mht;*.mhtml)|*.mht;*.mhtml|" +
                    "Rich Text Format (*.rtf)|*.rtf|" + "Plain Text (*.txt)|*.txt|" +
                    "Image (*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.tif;*.tiff;*.wdp)|*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.tif;*.tiff;*.wdp"
            }

            If dialog.ShowDialog(Me) = True Then
                Using stream = New MemoryStream()

                    ' Save RichTextBox content to RTF stream.
                    Dim textRange = New TextRange(Me.richTextBox.Document.ContentStart, Me.richTextBox.Document.ContentEnd)
                    textRange.Save(stream, DataFormats.Rtf)

                    stream.Position = 0

                    ' Convert RTF stream to output format.
                    DocumentModel.Load(stream, LoadOptions.RtfDefault).Save(dialog.FileName)
                    Process.Start(dialog.FileName)

                End Using
            End If

        End Sub

        Private Sub Cut(sender As Object, e As ExecutedRoutedEventArgs)

            Me.Copy(sender, e)

            ' Clear selection.
            Me.richTextBox.Selection.Text = String.Empty

        End Sub

        Private Sub Copy(sender As Object, e As ExecutedRoutedEventArgs)

            Using stream = New MemoryStream()

                ' Save RichTextBox selection to RTF stream.
                Me.richTextBox.Selection.Save(stream, DataFormats.Rtf)

                stream.Position = 0

                ' Save RTF stream to clipboard.
                DocumentModel.Load(stream, LoadOptions.RtfDefault).Content.SaveToClipboard()

            End Using

        End Sub

        Private Sub Paste(sender As Object, e As ExecutedRoutedEventArgs)

            Using stream = New MemoryStream()

                ' Save RichTextBox content to RTF stream.
                Dim textRange = New TextRange(Me.richTextBox.Document.ContentStart, Me.richTextBox.Document.ContentEnd)
                textRange.Save(stream, DataFormats.Rtf)

                stream.Position = 0

                ' Load document from RTF stream and prepend or append clipboard content to it.
                Dim document = DocumentModel.Load(stream, LoadOptions.RtfDefault)
                Dim position = If(DirectCast(e.Parameter, String) = "prepend", document.Content.Start, document.Content.End)
                position.LoadFromClipboard()

                stream.Position = 0

                ' Save document to RTF stream.
                document.Save(stream, SaveOptions.RtfDefault)

                stream.Position = 0

                ' Load RTF stream into RichTextBox.
                textRange.Load(stream, DataFormats.Rtf)

            End Using

        End Sub

        Private Sub CanSave(sender As Object, e As CanExecuteRoutedEventArgs)

            If Me.richTextBox IsNot Nothing Then
                Dim document = Me.richTextBox.Document
                Dim startPosition = document.ContentStart.GetNextInsertionPosition(LogicalDirection.Forward)
                Dim endPosition = document.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward)
                e.CanExecute = startPosition IsNot Nothing AndAlso endPosition IsNot Nothing AndAlso startPosition.CompareTo(endPosition) < 0
            Else
                e.CanExecute = False
            End If

        End Sub

        Private Sub CanCut(sender As Object, e As CanExecuteRoutedEventArgs)

            e.CanExecute = Me.richTextBox IsNot Nothing AndAlso Not Me.richTextBox.Selection.IsEmpty

        End Sub

        Private Sub CanCopy(sender As Object, e As CanExecuteRoutedEventArgs)

            e.CanExecute = Me.richTextBox IsNot Nothing AndAlso Not Me.richTextBox.Selection.IsEmpty

        End Sub

        Private Sub CanPaste(sender As Object, e As CanExecuteRoutedEventArgs)

            e.CanExecute = Me.richTextBox IsNot Nothing AndAlso Me.richTextBox.IsKeyboardFocused

        End Sub

    End Class

End Namespace

Check next sample.