2009-09-11 10 views
18

W aplikacji WPF chcę zbudować panel wyjściowy "Znajdź w plikach", w którym mogę przesyłać strumieniowo dużą ilość tekstu, bez konieczności ponownego przydzielania pamięci w każdym wierszu, np. TextBox. zrobić.WPF Multiline TextBox dla dużej zawartości

WPF TextBox ma jedną właściwość Text, która przechowuje ciąg ciągły. Za każdym razem chcę dodać treść, muszę zrobić textBox.Text += "New Text", co jest złe.

Idealnie byłoby, gdyby sterowanie było wirtualne i wymagałoby minimum zasobów, tylko dla widocznych linii.

Pomyślałem o użyciu standardu ListBox z VirtualizingStackPanel, ale nie pozwala to na wybór tekstu między wierszami.

(Przy każdej nowej linii dodaje, chcę kontrola zaktualizować)

Wszelkie sugestie?

+0

Skorzystaj z panelu stosów zamiast z pola listy –

+1

@Tymothy - w jaki sposób umożliwiłoby to zaznaczanie tekstu między wierszami? –

+4

Dla osób, które natknęły się na to pytanie, ponieważ zauważyły, że często zmieniające się (w moim przypadku tylko do odczytu) pole tekstowe ma cechy wycieku pamięci, należy ustawić UndoLimit na coś innego niż domyślne -1. Domyślna wartość -1 dla pola tekstowego pozwoli na nieograniczony wzrost historii cofania. – Derrick

Odpowiedz

17

Jeśli nie spodziewasz się więcej niż dziesięciu tysięcy wyników wyszukiwania w aplikacji, kontrola TextBlock lub wielowierszowy TextBox tylko do odczytu będą wystarczające.

Klasa TextBox ma metodę AppendText(), która powinna być wystarczająco szybka.

Jeśli potrzebujesz podświetlania/formatowania tekstu, to może chcesz użyć RichTextBox.

+1

Dzięki codymanix, MSDN doc mówi: Metoda AppendText umożliwia użytkownikowi dołączanie tekstu do zawartości formantu tekstowego bez użycia konkatenacji tekstu, co może zapewnić lepszą wydajność, gdy wymagane jest wiele konkatenacji. Po obejrzeniu implementacji wewnątrz .NET Reflector, AppendText jest dokładnie tym, czego potrzebuję. – decasteljau

+2

Wystąpił problem z wydajnością tego rozwiązania. :(TextBox pobiera zbyt dużo zasobów interfejsu użytkownika (CPU), gdy zalewamy kontrolę tysiącami linii. TextBox nie jest wirtualny i wykonuje złożone obliczenia przy każdym wywołaniu AppentText() Myślę, że potrzebowalibyśmy kontroli, która spowoduje jej odświeżenie i układ w wirtualny sposób, jak zrobił ItemControl: – decasteljau

+10

Należy pamiętać, że pole tekstowe może przechowywać każdy z twoich dodatków w celu cofnięcia operacji. Możesz chcieć zmienić pole UndoLimit w polu tekstowym. – Kelly

0

Czy rozważałeś lub wypróbowałeś kontrolkę RichTextBox?

+0

Próbowaliśmy, ale wydajność stała się katastrofalna, prawdopodobnie z powodu przesady związanej z formatowaniem ciągów znaków, której nie potrzebuję. – decasteljau

+0

Dzięki za poinformowanie mnie. @ Odpowiedź codymanix brzmi idealnie - nie wiedziałem o tym. –

-1

StringBuilder, po prostu dołączyć tekst do konstruktora ciąg i zamiast robić

textBox.Text += moreText; 

zrobić

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

ten powinien dbać o algorytmie do Schlemiel the Painter's.

Oczywiście konstruktor łańcuchów powinien być członkiem twojej klasy, aby istniał przez cały okres życia obiektu.

+0

za każdym razem, gdy wywołasz ToString() w StringBuilder, przydziela nowy, ciągły ciąg zawierający połączone ciągi. Ponieważ będę cały czas dołączał nowe linie do kontroli, ja tego dokładnie nie chcę. Dla każdej nowej linii chcę, aby kontrola była aktualizowana. – decasteljau

5

Jeśli masz naprawdę dużą zawartość, to niestety wszystkie pola tekstowe WPF i podobne elementy sterujące są bardzo wolne. Zobacz this question. Możesz użyć AvalonEdit jako zamiennika.