Question

What would be a good approach to display and edit large amount of unformatted text (just like notepade does) using WPF? Loading a big string into a TextBox makes the UI unresponsive. The overall performance is not nearly comparable with TextBox Controls of previous Microsoft UI Frameworks.

What options do I have to solve this problem. I do not want to block the UI thread while the text control loads the text. Also I might need some sort of "virtualization" because it might not be a good idea to load the whole text into the control (I guess that 20MB of text would create a lot of glyphs even if they are not visible). It seems that TextBox doesn't even have an AppenText() Method anymore so I don't even have a way to control asynchronous loading of the text.

Isn't this a common problem? It seems that WPF does not provide anything for this out of the box. Why is this so?

Was it helpful?

Solution

AvalonEdit, the text editor in SharpDevelop, was written completely from scratch in WPF and is optimized for large amounts of text. It doesn't support rich text (although it does support syntax highlighting and other cool features such as folding). I think this might fit your bill perfectly.

Here is an article on the editor written by the developer:

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

OTHER TIPS

I am not sure if this helps, but have you tried using FlowDocumentPageViewer and FlowDocumentReader?

It also has very good annotations support and looks ideal for loading documents in text format.

The problem is that the TextBox is a single container element. List controls, such as ListBox virtualize very well because of container recycling. There really isn't anything simple that you can do to speed up the TextBox.

But the TextBox control does have an AppendText() method:

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

So yes, you can use this to dynamicly add some text just like you mentioned.

You can just use a textbox with a style that gives the user more room to view the text. There are probably more advanced controls from Telerik and others but if you don't require editing options that should suffice.

You could always mix and match technologies: you could drop a WinForms TextBox onto a WPF parent. You lose things like styling, opacity, animation, transforms, etc., but if all that matters is editing text, the WinForms TextBox does that just fine.

Have you tried the WPF RichTextBox? You'll definitely want to read up on the FlowDocument information if you go this route.

You could use FlowDocument, but this doesn't work out of the box to bind to the Document property of a FlowDocument in MVVM.

Another solution is using FlowDocumentScrollViewer and bind to its Document property.

(or you could even use a FlowDocumentReader and bind its Document property, similar to the FlowDocumentScrollViewer. This gives you a different UI.)

The View:

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

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

see also this for extra performance tips: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-text#flowdocument-textblock-and-label-controls

How about trying something like this:

Keep the whole string in memory but show only a 'slice' of it in the textbox. Size of the that sliced string would be dynamically calculated depending on the size of textbox, font size etc.

Of course this involves a lot of not trivial code for proper displaying, synchronizing and so on, but it seems the way to go.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top