2009-04-30 19 views
6

Was wäre ein guter Ansatz zum Anzeigen und Bearbeiten einer großen Menge unformatierten Textes (genau wie Notepad) mit WPF? Wenn Sie eine große Zeichenfolge in eine TextBox laden, reagiert die Benutzeroberfläche nicht mehr. Die Gesamtleistung ist nicht annähernd vergleichbar mit TextBox Controls früherer Microsoft UI Frameworks.Wie bearbeite/bearbeite ich große Textmengen in WPF?

Welche Möglichkeiten habe ich, um dieses Problem zu lösen haben. Ich möchte den UI-Thread nicht blockieren, während das Textsteuerelement den Text lädt. Auch könnte ich eine Art von "Virtualisierung" benötigen, weil es nicht eine gute Idee ist, den gesamten Text in das Steuerelement zu laden (ich denke, dass 20 MB Text eine Menge Glyphen erzeugen würde, auch wenn sie nicht sichtbar sind). Es scheint, dass TextBox noch nicht einmal eine AppenText() -Methode hat, so dass ich nicht einmal eine Möglichkeit habe, das asynchrone Laden des Textes zu kontrollieren.

Ist das nicht ein allgemeines Problem? Es scheint, dass WPF nichts dafür bereithält. Warum ist das so?

+0

Ich spielte nur für ein bisschen damit. Das Problem scheint etwas mit der Berechnung der Scroll-Region zu tun zu haben. Wenn Sie die Bildlaufleiste deaktivieren, geht die Problemart weg - es sei denn, Sie drücken STRG + Ende (und dann muss es die untere oder etwas berechnen) die Inhaltsvorlage für die Textbox ist ein Scrollviewer. Vielleicht hat das Problem mehr mit der Optimierung des Scrollviewer zu tun. Keine Antwort, aber vielleicht ein Hinweis? – JMarsch

Antwort

1

AvalonEdit, der Texteditor in SharpDevelop, wurde von Grund auf neu in WPF geschrieben und ist für große Textmengen optimiert. Es unterstützt keinen Rich Text (obwohl Syntax-Highlighting und andere coole Funktionen wie Falten unterstützt werden). Ich denke, das passt perfekt zu Ihrer Rechnung.

Hier ist ein Artikel über den vom Entwickler geschrieben Editor:

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

+1

Ich habe auch die Schlussfolgerung, dass das Schreiben Ihrer eigenen Textkontrolle wahrscheinlich die beste Lösung ist. Es ist allerdings ein bisschen traurig. – bitbonk

+3

-1. Ich habe AvalonEdit mit 4MB oder größeren Dateien mit schrecklichen Ergebnissen verwendet. Extrem buggy und stürzt meine App wie ein wütender Bomber ab. – code4life

+1

Ich habe gerade ein neues VS WPF C# -Projekt erstellt, das NuGet AvalonEdit.Sample-Paket hinzugefügt, StartupUri geändert, run und voila !, die AvalonEdit-Anwendung läuft einwandfrei. Eröffnet eine 4MB Textdatei mit 8k Zeilen in weniger als einer Sekunde, während TextBlock 22 Sekunden dauerte. Definitiv könnte ein Ersatz für TextBlock sein. –

1

Sie können nur ein Textfeld mit einem Stil verwenden, die dem Anwender mehr Raum gibt den Text anzuzeigen. Es gibt wahrscheinlich erweiterte Steuerelemente von Telerik und anderen, aber wenn Sie keine Bearbeitungsoptionen benötigen, sollten diese ausreichen.

+0

Das Hauptproblem ist hier Leistung und Benutzerfreundlichkeit. Ich möchte den UI-Thread nicht blockieren, während das Textsteuerelement den Text lädt. Außerdem könnte eine Art "Virtualisierung" erforderlich sein, da es möglicherweise keine gute Idee ist, den gesamten Text in das Steuerelement zu laden (20MB Text würde viel erzeugen) von Glyphen). – bitbonk

+0

In diesem Fall würde ich mit einer Drittparteikontrolle gehen. Sie können die zusätzlichen Formatierungsfunktionen entfernen und einfach wie Notepad beibehalten. Ein Drittanbieter-Steuerelement sollte in der Lage sein, die Menge an Text, über die Sie sprechen, besser zu handhaben. Sie können den Text auch in einen anderen Thread laden und nach dem Laden an das Steuerelement binden. – Lukasz

-1

Wie wäre es so etwas wie dies versuchen:

die gesamte Zeichenfolge im Speicher halten, zeigen aber nur eine ‚Scheibe‘ davon in die Textbox. Die Größe der geschnittenen Zeichenfolge würde dynamisch berechnet, abhängig von der Größe des Textfelds, der Schriftgröße usw.

Natürlich beinhaltet dies eine Menge nicht trivialer Code für korrektes Anzeigen, Synchronisieren und so weiter, aber es scheint der Weg zu sein gehen.

1

Sie könnten immer mischen und zusammenzupassen Technologien: Sie WinForms TextBox auf eine WPF Eltern fallen könnte. Sie verlieren Dinge wie Styling, Opazität, Animation, Transformationen usw., aber wenn alles was zählt, ist das Bearbeiten von Text, die WinForms TextBox macht das gut.

+0

Das ist traurig, aber wahrscheinlich die beste Option. – bitbonk

3

Ich bin mir nicht sicher, ob das hilft, aber haben Sie versucht mit FlowDocumentPageViewer und FlowDocumentReader?

Es hat auch sehr gute Anmerkungen Unterstützung und sieht zum Laden von Dokumenten in Textformat ideal.

2

Das Problem besteht darin, dass die TextBox ein einzelnes Containerelement ist. List-Steuerelemente, wie ListBox, werden aufgrund des Container-Recyclings sehr gut virtualisiert. Es gibt wirklich nichts Einfaches, was Sie tun können, um die TextBox zu beschleunigen.

Aber die TextBox-Steuerelement funktioniert ein AppendText() Methode haben:

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

Also ja, können Sie diese verwenden, um dynamisch einen Text hinzufügen wie Sie erwähnt haben.

+0

Cool, ich las die Dokumente und die ererbten Mitglieder wo versteckt. Da AppendText() von TextBoxBase kommt, habe ich es nicht gesehen. – bitbonk

+0

Das funktioniert gut, und es ist schnell: Ich kann in einer Sekunde 10.000 neue Zeilen zu einer TextBox hinzufügen. Da alles virtualisiert ist, ist das Scrollen sehr schnell. – Contango

1

Haben Sie die WPF versucht RichTextBox? Wenn Sie diese Route verwenden, sollten Sie unbedingt die FlowDocument-Informationen lesen.

+0

Ich bin überrascht, etwas, das diese grundlegende nicht aus der Box behandelt wird. Es ist überhaupt nicht intuitiv, wie man Text an eine Richtextbox bindet. – BraveNewMath

0

Sie Flowdocument verwenden könnten, aber dies aus der Box auf die Dokument Eigenschaft zu binden, nicht funktioniert von einem FlowDocument in MVVM.

Eine andere Lösung wird mit Flowdocumentscrollviewer und binden an seine Dokument Eigenschaft.

(. Oder Sie sogar einen Flowdocumentreader und binden ihre Dokument Eigenschaft, ähnlich dem Flowdocumentscrollviewer verwenden könnte Dies gibt Ihnen eine andere Benutzeroberfläche.)

The View:

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

Das 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)); 
     } 
    } 

siehe auch das für zusätzliche Performance-Tipps: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-text#flowdocument-textblock-and-label-controls

Verwandte Themen