Frage

Ich überlege, um eine WPF- oder Silverlight-App zu erstellen, die wie ein Terminalfenster verwendet. Außer, da es in WPF / Silverlight ist, können Sie das Terminalerlebnis mit Effekten, Bildern usw. verbessern

Ich versuche, den besten Weg herauszufinden, um ein Terminal zu emulieren. Ich weiß, wie man mit der VT100-Emulation bis zur Analyse usw. umgeht, aber wie man es anzeigt? Ich habe die Verwendung einer RichTextbox in Betracht gezogen und konvertieren die VT100-Escape-Codes im Wesentlichen in RTF.

Das Problem, das ich damit sehe, ist Leistung. Das Terminal kann jeweils nur ein paar Zeichen erhalten und in der Lage sein, sie in das Textfeld AS-WE-Go-Go-Gehen, das ich in der Textbox laden kann. Damit jede Loading 'Session' abgeschlossen ist, müsste es RTF vollständig beschreiben. Wenn beispielsweise die aktuelle Farbe rot ist, benötigt jede Last in das Textfeld die RTF-Codes, um den Text rot zu machen, oder ich gehe davon aus, dass das RTB es nicht als rot lädt.

Dies scheint sehr redundant zu sein - das resultierende RTF-Dokument, das von der Emulation erbaut wurde, ist äußerst unordentlich. Auch die Bewegung des Carets scheint nicht, als würde es von der RTB ideal behandelt werden. Ich brauche etwas Besonderes, Methinks, aber das macht mir Angst!

hoffen, helle Ideen oder Zeiger auf vorhandene Lösungen zu hören. Vielleicht gibt es einen Weg, ein echtes Terminal und ein Overlay-Zeug darauf einzufügen. Das einzige, was ich gefunden habe, ist eine alte Winforms-Kontrolle.

update: Sehen Sie, wie die vorgeschlagene Lösung aufgrund von perf in meiner Antwort fehlschlägt. :(
VT100 Terminalemulation in Windows WPF oder Silverlight

War es hilfreich?

Lösung

Wenn Sie versuchen, dies mit RichTextbox und RTF implementieren zu können, werden Sie schnell in viele Einschränkungen gelangen und sich viel mehr Zeit verbringen, um die Unterschiede umzugehen, als wenn Sie die Funktionalität selbst implementiert haben.

In der Tat ist es ziemlich einfach, die VT100-Anschlussemulation mit WPF zu implementieren. Ich weiß, weil ich gerade jetzt einen fast vollständigen VT100-Emulator in einer Stunde implementiert habe. Um genau zu sein, habe ich alles implmentiert, außer:

  • Tastatureingabe,
  • alternative Zeichensätze,
  • ein paar esoterische VT100-Modi, die ich noch nie gesehen habe,

Die interessantesten Teile waren:

  • Die doppelte Breite / doppelte Höhenfiguren, für die ich Rendertransform und Rendertransformorigin
  • verwendet habe
  • das Blinken, für den ich eine Animation auf einem gemeinsam genutzten Objekt genutzt habe, sodass alle Zeichen zusammen blinken
  • Die Unterstreichung, für die ich ein Gitter und ein Rechteck benutzt habe, somit er eher wie ein VT100-Display
  • aussehen würde
  • Der Cursor und die Auswahl, für den ich auf den Zellen selbst eine Flagge eingesetzte und DataTriggers verwenden, um das Display
  • zu ändern
  • Die Verwendung von einem eindimensionalen Array und einem verschachtelten Array, das auf dieselben Objekte zeigt, um es einfach zu machen, Scrollen und Selection

hier ist das xaml:

generasacodicetagpre.

und hier ist der Code:

generasacodicetagpre.

Beachten Sie, dass, wenn Sie das visuelle Styling nicht mögen, das terminalcell Datatemplate aktualisieren. Zum Beispiel könnte der Cursor ein blinkendes Rechteck anstelle eines Festkörpers sein.

Dieser Code hat Spaß gemacht, um zu schreiben. Hoffentlich ist es für Sie nützlich. Es hat wahrscheinlich einen oder zwei Fehler (oder drei), da ich es nie tatsächlich ausgeführt habe, aber ich erwarte, dass diese leicht geräumt werden. Ich würde einen Bearbeiten auf diese Antwort begrüßen, wenn Sie etwas reparieren.

Andere Tipps

Der einzige Weg, um Text effektiv anzuzeigen, verwendet TextFormatter. Ich habe den Telnet-Client für textbasierte RPG-Spiele implementiert und funktioniert ziemlich gut. Sie können Quellen bei http://mudclient.codeplex.com

überprüfen

Ich verstehe nicht, warum Sie sich von der RTF-RTF verärgern würden, die gewunden werden.Ja, es wird.Es ist jedoch nicht Ihre Belastung, um damit umzugehen, ein Microsoft-Programmierer hat vor einiger Zeit getan, um den Code schreiben zu müssen, um den Confoluted RTF zu rendern.Es funktioniert gut und ist für Sie völlig undurchsichtig.

Ja, es wird nicht super schnell sein.Aber was das Hey, Sie emulieren ein 80x25-Display, das verwendet wurde, um bei 9600 Baud zu laufen.Die Kontrolle vollständig ersetzen, um zu versuchen, es optimal zu gestalten, macht wenig Sinn und wird ein Großunternehmen sein.

Nun, um meinen Status zu melden, habe ich festgestellt, dass dies nicht wirklich machbar mit WPF oder Silverlight ist.

Das Problem mit dem vorgeschlagenen Ansatz besteht darin, dass es 80 * 24 Textblocks plus andere Elemente gibt, mit mehreren Bindungen für Vorgeschichte, Backcolor usw., wenn der Bildschirm blättern muss, wobei jede dieser Bindungen erneut ausgewertet werden muss, und Es ist sehr, sehr langsam. Aktualisieren des gesamten Bildschirms dauert einige Sekunden. In meiner App ist das nicht akzeptabel, der Bildschirm wird ständig scrollen.

Ich habe viele verschiedene Dinge ausprobiert, um es zu optimieren. Ich habe versucht, einen Textblock mit 80 Läufen pro Zeile zu verwenden. Ich habe versucht, die Änderungsbenachrichtigungen zu bapieren. Ich habe versucht, es so ein "Scroll" -EVer-Ereignis manuell auf dem neuesten Stand zu bringen. Nichts hilft wirklich - der langsame Teil aktualisiert die Benutzeroberfläche, nicht so, wie es fertig ist.

Eine Sache, die geholfen hätte, wenn ich einen Mechanismus entwickelte, der keinen Textblock hatte oder für jede Zelle läuft, sondern nur Textblocks ändern, wenn sich der Textstil ändert. So wäre eine Zeichenfolge desselben Farbtextes zum Beispiel nur 1 Textblock. Das wäre jedoch sehr kompliziert, und am Ende würde es nur Szenarien helfen, die wenig Stilvariationen auf dem Bildschirm aufweisen. Meine App wird viele Farben haben, die von (denken ansi Art), also wäre es in diesem Fall noch langsam.

Eine andere Sache, an die ich dachte, würde helfen, wenn ich die Textblocks nicht aktualisierte, sondern eher als der Bildschirm scrollte. So wären Textblocks von oben nach unten und dann würden nur die neuen Aktualisierung benötigen. Ich habe es geschafft, diese Arbeit mit einer beobachtbaren Sammlung zu erlangen. Es half, aber es ist noch viel zu langsam!

Ich habe sogar eine benutzerdefinierte WPF-Steuerung unter Verwendung von Onrender betrachtet. Ich habe einen erstellt, der DrawingCtext.Rendertext auf verschiedene Weise verwendete, um zu sehen, wie schnell es sein könnte. Aber auch das ist zu verdammt langsam, um den Bildschirm ständig zu aktualisieren.

das ist das, das habe ich dieses Design aufgegeben. Ich schaue stattdessen ein echtes Konsolenfenster, wie hier beschrieben:

Keine Ausgabe an die Konsole von einer WPF-Anwendung?

Ich mag das nicht wirklich, da das Fenster jedoch vom Hauptfenster getrennt ist, also suche ich nach einer Möglichkeit, das Konsolenfenster in das WPF-Fenster einzubetten, falls das noch möglich ist. Ich werde eine andere so fragen, dass ich damit frage frage und werde es hier verbinden, wenn ich tue.

update: einbetten Das Konsolenfenster fehlgeschlagen, da es nicht freundlich dauert, dass die Titelleiste entfernt wurde. Ich habe es als Low-Level-Painting-Custom WinForms-Steuerung implementiert und gehe das in WPF aus. Das funktioniert wunderschön und nach einigen Optimierungen, es ist sehr schnell.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top