RichTextBox занимает много памяти и тормозит

В приложении имеется TabControl, во вкладках которого находится некоторое количество RichTextBox с текстом. Переключение между вкладками происходит с заметной задержкой и при каждом переключении растет занимаемая память - если один раз пройти по всем вкладкам, то занимаемая память увеличивается на ~150 мб, а ещё пощёлкать - и того больше. При этом память может освободиться, но только через несколько часов работы программы. Если же использовать, например TextBlock, то проблем с памятью нет (задержка есть, но небольшая), но у него нет выделения текста, а оно необходимо.
Можно ли как-то настроить RichTextBox для решения проблемы, или может есть другой контрол с выделением, форматированием и гиперссылками?

Вот тестовая разметка:

<Window x:Class="TestRichTextBoxApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestRichTextBoxApp"
        xmlns:vm="clr-namespace:TestRichTextBoxApp.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    <DockPanel>
        <TabControl ItemsSource="{Binding TabControlViewModel.Tabs,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                    VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
            <TabControl.Resources>
                <DataTemplate x:Key="HeaderTemplate" DataType="{x:Type vm:TabItemViewModel}">
                    <StackPanel Background="Transparent">
                        <TextBlock Text="{Binding Header}"/>
                    </StackPanel>
                </DataTemplate>
                <DataTemplate x:Key="ContentTemplate" DataType="{x:Type vm:TabItemViewModel}">
                    <ScrollViewer x:Name="scrollViewer" 
                                  Background="White" 
                                  VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
                        <ItemsControl ItemsSource="{Binding Doc.SubDocs}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel>
                                        <RichTextBox IsDocumentEnabled="True" 
                                                     IsReadOnly="True" 
                                                     BorderThickness="0"
                                                     Padding="0,0,0,5"  
                                                     UndoLimit="0"
                                                     IsUndoEnabled="False">
                                            <RichTextBox.Document>
                                                <FlowDocument>
                                                    <Paragraph>
                                                        <Run FontWeight="Bold">
                                                            <Run.Text>
                                                                <MultiBinding StringFormat="{}[{0:dd MMMM, HH:mm}] {1}: " >
                                                                    <Binding Path="DateTime"></Binding>
                                                                    <Binding Path="Creator"></Binding>
                                                                </MultiBinding>
                                                            </Run.Text>
                                                        </Run>
                                                        <Run Text="{Binding Text}"></Run>
                                                    </Paragraph>
                                                </FlowDocument>
                                            </RichTextBox.Document>
                                        </RichTextBox>
                                        <!--<TextBlock TextWrapping="Wrap">
                                            <Run FontWeight="Bold">
                                                <Run.Text>
                                                    <MultiBinding StringFormat="{}[{0:dd MMMM, HH:mm}] {1}: " >
                                                        <Binding Path="DateTime"></Binding>
                                                        <Binding Path="Creator"></Binding>
                                                    </MultiBinding>
                                                </Run.Text>
                                            </Run>
                                            <Run Text="{Binding Text}"></Run>
                                        </TextBlock>-->
                                    </StackPanel>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </ScrollViewer>
                </DataTemplate>
            </TabControl.Resources>
            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="HeaderTemplate" Value="{StaticResource HeaderTemplate}"/>
                    <Setter Property="ContentTemplate" Value="{StaticResource ContentTemplate}"/>
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>
    </DockPanel>
</Window>

Тестовая VM:

using System.Collections.ObjectModel;
using TestRichTextBoxApp.Models;

namespace TestRichTextBoxApp.ViewModels
{
    class MainWindowViewModel : ViewModel
    {
        TabControlViewModel tabControlViewModel;

        public TabControlViewModel TabControlViewModel { get => tabControlViewModel; set => Set(ref tabControlViewModel, value); }
        public MainWindowViewModel()
        {
            TabControlViewModel = new TabControlViewModel();
        }
    }

    class TabItemViewModel : ViewModel
    {
        string header;
        public string Header { get => header; set => Set(ref header, value); }

        Doc doc;
        public Doc Doc { get => doc; set => Set(ref doc, value); }
    }

    class TabControlViewModel : ViewModel
    {
        public ObservableCollection<TabItemViewModel> Tabs { get; set; } = new ObservableCollection<TabItemViewModel>();
        internal TabItemViewModel SelectedItem { get; set; }
        public TabControlViewModel()
        {
            var storage = Storage.Instance;
            foreach (var item in storage.Docs)
            {
                Tabs.Add(new TabItemViewModel { Header = item.Title, Doc = item, });
            }
        }
    }
}

Тестовая модель:

using System;
using System.Collections.ObjectModel;

namespace TestRichTextBoxApp.Models
{
    class Doc : BaseObject
    {
        int _id;
        string _title;
        public ObservableCollection<SubDoc> SubDocs { get; set; } = new ObservableCollection<SubDoc>();
        public string Title { get => _title; set => Set(ref _title, value); }
        public int Id { get => _id; set => Set(ref _id, value); }
    }
    class SubDoc : BaseObject
    {
        int _id;
        string _creator;
        int _doc;
        DateTime _dateTime;
        string _text;

        public int Id { get => _id; set => Set(ref _id, value); }
        public string Creator { get => _creator; set => Set(ref _creator, value); }
        public int Doc { get => _doc; set => Set(ref _doc, value); }
        public DateTime DateTime { get => _dateTime; set => Set(ref _dateTime, value); }
        public string Text { get => _text; set => Set(ref _text, value); }
    }

    class Storage
    {
        private readonly string[] strArr =
        {
            "Давайте не будем укрепляться в мысли, что чистый разум не скован границами",
            "Частотность поисковых запросов даёт нам право принимать самостоятельные решения",
            "Базовый вектор развития не позволил союзу развалиться!",
            "Допустим, цены на бензин начинают падать",
            "Эксперты утверждают, что доблесть наших правозащитников расставила все точки над i",
            "Зима близко",
            "Ясность нашей позиции очевидна: выбранный нами инновационный путь обеспечивает широкому кругу (специалистов) участие в формировании новых принципов формирования материально-технической и кадровой базы. Господа, постоянный количественный рост и сфера нашей активности напрямую зависит от существующих финансовых и административных условий. Предварительные выводы неутешительны: постоянное информационно-пропагандистское обеспечение нашей деятельности способствует повышению качества как самодостаточных, так и внешне зависимых концептуальных решений. Вот вам яркий пример современных тенденций - экономическая повестка сегодняшнего дня, в своём классическом представлении, допускает внедрение распределения внутренних резервов и ресурсов. Задача организации, в особенности же перспективное планирование требует от нас анализа переосмысления внешнеэкономических политик. Противоположная точка зрения подразумевает, что представители современных социальных резервов неоднозначны и будут обнародованы. Кстати, некоторые особенности внутренней политики формируют глобальную экономическую сеть и при этом - представлены в исключительно положительном свете. Противоположная точка зрения подразумевает, что тщательные исследования конкурентов, инициированные исключительно синтетически, объединены в целые кластеры себе подобных. Как уже неоднократно упомянуто, независимые государства преданы социально-демократической анафеме.",
        };
        private readonly string[] strArr2 =
        {
            "Tom",
            "Bob",
            "Kate",
            "Ann",
        };
        static Storage _instance;
        public static Storage Instance => _instance ?? (_instance = new Storage());
        public ObservableCollection<Doc> Docs { get; set; } = new ObservableCollection<Doc>();
        public Storage()
        {
            Random random = new Random();
            for (int i = 0; i < 10; i++)
            {
                Doc doc = new Doc
                {
                    Id = i,
                    Title = "Title " + i,
                };
                for (int j = 0; j < 100; j++)
                {
                    doc.SubDocs.Add(new SubDoc
                    {
                        DateTime = DateTime.Now,
                        Creator = strArr2[random.Next(strArr2.Length)],
                        Doc = i,
                        Id = j,
                        Text = strArr[random.Next(strArr.Length)],
                    });
                }
                Docs.Add(doc);
            }
        }
    }
}

Ответы (0 шт):