2009-04-30 21 views
6

WPFを使用して大量の書式なしテキストを表示して編集するにはどうすればよいでしょうか(メモ帳と同様)大きな文字列をTextBoxに読み込むと、UIが応答しなくなります。全体的なパフォーマンスは、以前のMicrosoft UI FrameworkのTextBoxコントロールとほとんど比較できません。WPFで大量のテキストを処理/編集するにはどうすればよいですか?

この問題を解決するにはどのようなオプションが必要ですか。テキストコントロールがテキストを読み込んでいる間にUIスレッドをブロックしたくありません。また、私は何らかの「仮想化」が必要かもしれません。なぜなら、テキスト全体をコントロールにロードするのは良い考えではないかもしれないからです(20MBのテキストは、表示されなくてもグリフをたくさん作成すると思います)。 TextBoxはAppenText()メソッドをもはや持っていないので、私はテキストの非同期ロードを制御する方法さえも持っていないようです。

これはよくある問題ではありませんか? WPFはこれをそのままの状態で提供するものではないようです。なぜこれはそうですか?

+0

私はちょっとだけ遊んだ。問題は、スクロール領域を計算することと関係があるようです。スクロールバーを無効にすると、問題の種類がなくなります.ctrl + endキーを押してから(底値などを計算しなければ) のコンテンツテンプレートはスクロールビューアです。スクロールビューアを最適化することと関連があるかもしれません。 答えはありませんが、ヒントかもしれません。 – JMarsch

答えて

1

SharpDevelopのテキストエディタAvalonEditは、WPFの最初から完全に書き込まれ、大量のテキスト用に最適化されています。リッチテキストはサポートしていません(ただし、構文の強調表示や折り畳みなどのクールな機能をサポートしています)。私はこれがあなたの法案に完全に合うかもしれないと思います。ここで

は、開発者によって書かれたエディタ上の記事です:

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

+1

私はあなた自身のテキストコントロールを書くことがおそらく最高の解決策であると結論づけています。しかし、少し悲しいです。 – bitbonk

+3

-1。私は恐ろしい結果を伴う4MB以上のファイルでAvalonEditを使用しました。非常にバグがあり、私のアプリは狂った爆撃機のようにクラッシュします。 – code4life

+1

新しいVS WPF C#プロジェクトを作成し、NuGet AvalonEdit.Sampleパッケージを追加し、StartupUriを変更して実行してください!、AvalonEditアプリケーションは正常に動作しています。 TextBlockは22秒かかりましたが、8秒間で4MBのテキストファイルを開きました。間違いなくTextBlockの代わりになる可能性があります。 –

1

テキストを表示するためのスペースをユーザーに与えるスタイルのテキストボックスを使用することができます。おそらく、Telerikや他のものより高度なコントロールがありますが、十分なはずの編集オプションは必要ありません。

は、メモリ内の文字列全体を保つが、テキストボックスに、それだけ「スライス」を示しています。このような何かをしようとしてについてはどのように

+0

ここでの主な問題はパフォーマンスと使いやすさです。私はUIのスレッドをブロックしたくないのですが、テキストコントロールがテキストを読み込んでいます。私は何らかの「仮想化」が必要かもしれません。なぜなら、テキスト全体をコントロールにロードするのは良い考えではないからです。グリフの)。 – bitbonk

+0

その場合、私は第三者のコントロールに行きます。余分なフォーマット機能を削除して、メモ帳のように簡単に保つことができます。第三者のコントロールは、あなたが話しているテキストの量をよりよく扱うことができるはずです。また、別のスレッドにテキストをロードし、読み込んだ後にコントロールにバインドすることもできます。 – Lukasz

-1

。そのスライスされた文字列のサイズは、テキストボックス、フォントサイズなどのサイズに応じて動的に計算されます。

もちろん、これは適切な表示、同期などのために些細ではないコードが多く含まれていますが、行く。

1

テクノロジをいつでも組み合わせることができます.WinForms TextBoxをWPFの親にドロップすることができます。スタイリング、不透明、アニメーション、トランスフォームなどの要素は失われますが、重要なのはテキストの編集だけであれば、WinFormsのTextBoxはそれだけです。

+0

これは悲しいことですが、おそらく最良の選択です。 – bitbonk

3

これが役立つかどうかはわかりませんが、FlowDocumentPageViewerFlowDocumentReaderを試してみましたか?

非常に優れたアノテーションもサポートされており、ドキュメントをテキスト形式で読み込むのに適しています。

2

問題は、TextBoxが単一のコンテナ要素であることです。 ListBoxなどのリストコントロールは、コンテナのリサイクルのために非常にうまく機能します。 TextBoxをスピードアップするためにできることは、単純にはありません。

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

そうです、あなたはあなたが言及しただけのようないくつかのテキストを追加dynamiclyするためにこれを使用することができます。

しかし、TextBoxコントロールはのappendText()メソッドを持っています。

+0

私はドキュメントと継承されたメンバーを非表示にしていました。 AppendText()はTextBoxBaseから来たので、私はそれを見ませんでした。 – bitbonk

+0

これはうまく動作し、速いです:約1秒で1万の新しい行をTextBoxに追加できます。そのすべてが仮想化されているので、スクロールは非常に迅速です。 – Contango

1

WPF RichTextBoxを試しましたか?あなたがこのルートに行くなら、間違いなくFlowDocumentの情報を読んでみたいです。

+0

私はこの基本的なことが箱から処理されない何かに驚いています。テキストをリッチテキストボックスにバインドする方法は、直感的ではありません。 – BraveNewMath

0

あなたはFlowDocumentを使用することができますが、これはドキュメントプロパティにバインドするために箱から出して動作しません。 MVVMのフロードキュメント

もう1つの解決策は、FlowDocumentScrollViewerを使用し、その文書プロパティにバインドします。

ビュー(または、あなたもFlowDocumentReaderを使用してFlowDocumentScrollViewerに似たそのドキュメントプロパティを、結合することができる。これは、あなたに別のUIを提供します。。):

<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

関連する問題