Многострочное текстовое поле WPF для большого содержимого

В приложении WPF я хочу создать панель вывода «Найти в файлах», в которой я могу передавать большое количество текста без перераспределения памяти в каждой строке, как это сделал бы TextBox.

WPF TextBox имеет единственное свойство Text, в котором хранится непрерывная строка. Каждый раз, когда я хочу добавить контент, мне нужно делать textBox.Text += "New Text", что плохо.

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

Я думал об использовании стандартного ListBox с VirtualizingStackPanel, но он не позволяет выделять текст по строкам.

(При добавлении каждой новой строки я хочу, чтобы элемент управления обновлялся)

Любое предложение?


person decasteljau    schedule 11.09.2009    source источник
comment
Попробуйте использовать панель стека вместо списка   -  person Timothy Khouri    schedule 12.09.2009
comment
@Timothy - как это разрешить выделение текста по строкам?   -  person Drew Noakes    schedule 12.09.2009
comment
Для людей, которые столкнулись с этим вопросом, потому что они обнаружили, что часто меняющееся (в моем случае только для чтения) текстовое поле имеет характеристики утечки памяти, обязательно установите UndoLimit на что-то другое, кроме значения по умолчанию -1. Значение по умолчанию -1 для текстового поля позволит неограниченный рост истории отмен.   -  person Derrick    schedule 17.11.2011


Ответы (4)


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

Класс TextBox имеет метод AppendText (), который должен быть достаточно быстрым для вас.

Если вам нужно выделение / форматирование текста, возможно, вы захотите использовать RichTextBox.

person codymanix    schedule 12.09.2009
comment
Спасибо codymanix, в документе MSDN говорится: Метод AppendText позволяет пользователю добавлять текст к содержимому текстового элемента управления без использования объединения текста, что может обеспечить лучшую производительность, когда требуется много объединений. Кроме того, после просмотра реализации внутри .NET Reflector, AppendText - это именно то, что мне нужно. - person decasteljau; 12.09.2009
comment
Это решение связано с проблемой производительности. :( TextBox занимает слишком много ресурсов пользовательского интерфейса (ЦП) при заполнении элемента управления тысячами строк. TextBox не является виртуальным и выполняет сложные вычисления при каждом вызове AppentText (). Я думаю, нам понадобится элемент управления, который его перерисовывает и макет виртуально, как это сделал бы ItemsControl. - person decasteljau; 14.09.2009
comment
Имейте в виду, что текстовое поле может хранить каждое из ваших добавлений для операций отмены. Возможно, вы захотите изменить поле UndoLimit в текстовом поле. - person Kelly; 01.07.2010

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

person Daniel Rose    schedule 19.05.2011
comment
Вау, это действительно отличное предложение. Программа AvalonEdit TextEditor решила мои проблемы при попытке поместить более 65 тыс. Символов в TextBox - person j00hi; 27.11.2019

Рассматривали или пробовали ли вы элемент управления RichTextBox? ?

person Drew Noakes    schedule 11.09.2009
comment
Мы пробовали, но производительность стала катастрофической, вероятно, из-за излишка, связанного с форматированием строк, в котором я не нуждаюсь. - person decasteljau; 12.09.2009
comment
Спасибо, что дал мне знать. Ответ @codymanix звучит идеально - я этого не знал. - person Drew Noakes; 12.09.2009

StringBuilder, просто добавьте текст в построитель String и вместо того, чтобы делать

textBox.Text += moreText;

do

myStringBuilder.Append(moreText);
textBox.Text = myStringBuilder.ToString();

Это должно позаботиться об алгоритме Schlemiel the Painter's.

Конечно, построитель строк должен быть членом вашего класса, чтобы он существовал на протяжении всего жизненного цикла вашего объекта.

person Carlo    schedule 11.09.2009
comment
каждый раз, когда вы вызываете ToString () в StringBuilder, он выделяет новую непрерывную строку, содержащую сцепленные строки. Поскольку я все время буду добавлять новые строки к элементу управления, мне это точно не нужно. Я хочу, чтобы элемент управления обновлялся для каждой новой строки. - person decasteljau; 12.09.2009