Binding to a RichTextBox in WPF

Published on Monday, December 11, 2017

I've been doing some WPF development the last couple of weeks, and one thing that bugged me was that there is no way (as far as I know) to bind content to a RichTextBox. This makes it kind of difficult to follow the MVVM pattern since the view model needs intimate knowledge of the view.

In my case, I wanted to bind the textbox against a resource using a pack:// URI, so I threw together some code to do this. I am far from an expert on WPF, so if you have any suggestions then please let me know!

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace MyApp.Controls
    public sealed class BindableRichTextBox : RichTextBox
        public static readonly DependencyProperty SourceProperty =
                typeof(Uri), typeof(BindableRichTextBox),
                new PropertyMetadata(OnSourceChanged));

        public Uri Source
            get => GetValue(SourceProperty) as Uri;
            set => SetValue(SourceProperty, value);

        private static void OnSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
            if (obj is BindableRichTextBox rtf && rtf.Source != null)
                var stream = Application.GetResourceStream(rtf.Source);
                if (stream != null)
                    var range = new TextRange(rtf.Document.ContentStart, rtf.Document.ContentEnd);
                    range.Load(stream.Stream, DataFormats.Rtf);

You can now use a binding as you normally would in your XAML (or simply set it directly).

<Window x:Class="MyApp.MyView"
        <ui:BindableRichTextBox Source="{Binding Licenses}" />
        <ui:BindableRichTextBox Source="pack://application:,,,/MyApp;component/MyApp/Resources/Document.rtf" />