Как обрабатывать / редактировать большой объем текста в WPF?

Что было бы хорошим подходом для отображения и редактирования большого количества неформатированного текста (так же, как notepade) с помощью WPF? Загрузка большой строки в текстовое поле делает пользовательский интерфейс невосприимчивым. Общая производительность не сопоставима с элементами управления TextBox предыдущих фреймворков Microsoft UI.

какие варианты у меня есть, чтобы решить эту проблему. Я не хочу блокировать поток пользовательского интерфейса, пока текстовый элемент управления загружает текст. Также мне может понадобиться какая-то" виртуализация", потому что возможно, не стоит загружать весь текст в элемент управления (я думаю, что 20 МБ текста создаст много символов, даже если они не видны). Кажется, что TextBox даже не имеет метода AppenText (), поэтому у меня даже нет способа контролировать асинхронную загрузку текста.

разве это не общая проблема? Похоже, что WPF ничего не предоставляет для этого из коробки. Почему это так?

8 ответов


AvalonEdit, текстовый редактор в SharpDevelop, был написан полностью с нуля в WPF и оптимизирован для больших объемов текста. Он не поддерживает богатый текст (хотя он поддерживает подсветку синтаксиса и другие интересные функции, такие как складывание). Я думаю, что это идеально подходит для вашего счета.

вот статья о редакторе, написанная разработчиком:

http://www.codeproject.com/KB/edit/AvalonEdit.aspx


Я не уверен, что это помогает, Но вы пробовали использовать FlowDocumentPageViewer и FlowDocumentReader?

Он также имеет очень хорошую поддержку аннотаций и идеально подходит для загрузки документов в текстовом формате.


проблема в том, что текстовое поле-это единый элемент-контейнер. Элементы управления списком, такие как ListBox, виртуализируются очень хорошо из-за переработки контейнеров. На самом деле нет ничего простого, что вы можете сделать, чтобы ускорить текстовое поле.

но элемент управления TextBox имеет метод AppendText ():

        TextBox tb = new TextBox();
        tb.AppendText("Hello");

Так что да, вы можете использовать это, чтобы динамично добавить текст, как вы упомянули.


вы можете просто использовать текстовое поле с стиль, который дает пользователю больше места для просмотра текста. Вероятно, есть более продвинутые элементы управления от Telerik и других, но если вам не нужны параметры редактирования, которых должно быть достаточно.


вы всегда можете смешивать и сопоставлять технологии: вы можете поместить текстовое поле WinForms на родителя WPF. Вы теряете такие вещи, как стиль, непрозрачность, анимация, преобразования и т. д., но если все, что имеет значение, это редактирование текста, текстовое поле WinForms делает это просто отлично.


вы пробовали WPF RichTextBox? Вы определенно захотите прочитать информацию о FlowDocument, если пойдете по этому маршруту.


можно использовать FlowDocument, но это не работает из коробки, чтобы привязать к документ свойства FlowDocument в MVVM.

другое решение использует FlowDocumentScrollViewer и обязать его документ собственность.

(или вы даже можете использовать FlowDocumentReader и обязать его документ свойство, подобное FlowDocumentScrollViewer. Это дает вам другой пользовательский интерфейс.)

Вид:

 <FlowDocumentScrollViewer Document="{Binding FlowDocument, Mode=OneWay}" />

ViewModel:

   FlowDocument fd = new FlowDocument();
        Paragraph p = new Paragraph();
        Run r = new Run();
        r.Text = "large text";
        p.Inlines.Add(r);
        fd.Blocks.Add(p);
        FlowDocument = fd;

 private FlowDocument _FlowDocument;
    public FlowDocument FlowDocument
    {
      get{ return _FlowDocument; }
      set
      {
        _FlowDocument = value;
        NotifyOfPropertyChange(nameof(FlowDocument));
      }
    }

см. также это для дополнительных советов по производительности: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-text#flowdocument-textblock-and-label-controls


Как насчет попробовать что-то вроде этого:

сохраните всю строку в памяти, но покажите только ее "срез" в текстовом поле. Размер этой нарезанной строки будет динамически вычисляться в зависимости от размера текстового поля, размера шрифта и т. д.

конечно, это включает в себя много нетривиального кода для правильного отображения, синхронизации и так далее, но, похоже, путь.