How do I handle/edit large amount of text in WPF? - wpf

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?

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

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://learn.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.

One other option is to use Scintilla.NET. It has the best performance for large amounts of texts I have seen so far. Loading large files is almost instantaneous. Even though it is a WinForms control, you can embed it into your WPF window with WindowsFormsHost container. There is syntax highlighting and some other features that should be more than enough for displaying unformatted text. From the downsides - since this is a WinForms control, it overlaps other WPF UI elements. Also there may be issues with resizing the control. Unfortunately, I don't see any better option than using a non-WPF control instead of the default TextBox and RichTextBox.

Related

Is WPF's FlowDocument content user-editable?

I understand and have read about using WPF's FlowDocument to create an XML style document on screen, but is the content presented editable by the user, or is it read only? And, if so, how is this done?
My question mostly centres around the use of the listitem control because it would be nice to be able to edit the order of the list items presented for use in my program, rather than me having to create my own custom control(s).
Regards.
FlowDocuments as objects are editable, if they can be edited in the UI depends on the controls that use them. If you use them in a Page they are not, if you use them in a RichTextBox they are.

Can not get image information from Silverlight RichTextEditor

I'm trying to use the Silverlight RichTextEditor in our website. Now we'd like to translate the content in richtextbox into HTML code to save and load.
However, as we know, the richtextbox control does not support the UIelements output. When we insert an image in the richtextbox, the richtextbox would use a inlineUIcontainer to show this image. The property Richtextbox.xaml does not include any information about the image. It just shows the code like "".
Does anyone have this problem and handle it before?
RichTextBox.Xaml strips out a lot of things, as a security safeguard (more for the setter than the getter as far as I recall, but it does it both ways so there are no round-trip surpises).
I recommend looking at the XAML Serializer written by David Poll on his blog (here: http://www.davidpoll.com/2010/07/25/to-xaml-with-love-an-experiment-with-xaml-serialization-in-silverlight/ ) as it can serialize RTB awesomely well (it's in fact one of the test cases he shows). David was a PM on the Silverlight XAML Parser in SL4, so he knows an awful lot about XAML.
But be careful when setting the .Xaml property, as you could mistakenly end up spinning up InlineUIContainer elements which load resources into your AppDomain that you don't want in there, so make sure you control the inputs or you strip them yourself very carefully.

WPF Combobox with auto-complete/auto-filter?

I am eager to find some solid (free, Open Source, or tutorial/example) code to make a WPF Combobox do autocomlete/autofilter as the user types. But everything I've tried so far has had some sort of problem...
A Reusable WPF Autocomplete TextBox came close, but I can't get it to work with more than one filter (more info here).
WPF autocomplete textbox/combobox doesn't work for me because it inherits from UserControl, and thus doesn't support the DataTemplates I need (for showing/selecting the value of one property for an object with multiple properties).
Automatically Filtering a ComboBox in WPF didn't work because it doesn't seem to ever find the EditableTextBox portion of the inherited ComboBox code (via (TextBox)base.GetTemplateChild("PART_EditableTextBox") which seems to always returns null).
Building a Filtered ComboBox for WPF just gets stuck in a refresh loop then overflows the stack after I type just a few letters.
Other things I've considered:
I know that Windows Forms' Combobox control has AutoCompleteMode and I could embed it in WPF, but I can't imagine it would play very well with my WPF data bindings.
Perhaps it is too complex and I need to simplify, maybe by building one-dimensional (single-property) ObservableCollections for the ComboBoxen... However, the challenge of applying multiple filters (one set by another control's value, and one from what the user is typing) to multiple controls using different views of the same DataSet would require a ridiculous amount of processing power to destroy and rebuild the list every time the user types a character!
So... I'm at wit's end. Any suggestions?
If your Combobox has some data source attached to it ,
just make
1-IsTextSearchEnabled = true.
2-IsEditable = true.
you are good to go
Try this one:
http://blogs.windowsclient.net/dragonz/archive/2010/02/23/autocomplete-textbox-control-for-wpf.aspx

Serializing WPF RichTextBox to XAML vs RTF

I have a RichTextBox and need to serialize its content to my database purely for storage purposes. It would appear that I have a choice between serializing as XAML or as RTF, and am wondering if there are any advantages to serializing to XAML over RTF, which I would consider as more "standard".
In particular, am I losing any capability by serializing to RTF instead of XAML? I understand XAML supports custom classes inside the FlowDocument, but I'm not currently using any custom classes (though the potential for extensibility might be enough reason to use XAML).
Update: I ended up going with RTF because of its support for text-encoded embedded images. XAML doesn't seem to include image data in its encoding, and XamlPackage encodes to binary, so RTF just works better for me. So far I haven't noticed any lack in capability.
If all your users are doing is typing in the RichTextBox and doing character formatting, RTF is as good as XAML. However there are many FlowDocument capabilities you may expose in your UI that are not convertible to RTF.
Here are some examples of FlowDocument (and RichTextBox) features that are not expressable in RTF or are implemented differently:
A Block can have an arbitrary BorderBrush, including gradient brushes with stops, VisualBrush
A Section has the HasTrailingParagraphBreakOnPaste property
Floater / ClearFloaters is implemented differently
Hyphenation can be enabled/disabled per block, not just per paragraph
WPF Styles and ResourceDictionaries can be included in the Resources property
Arbitrary WPF UI such as bound CheckBoxes, etc, can be embedded inside the RichTextBox and can be cut-and-pasted from other windows.
For example, suppose you want to allow users to drag or cut/paste in a "current date/time" field into your RichTextBox that would always show the current date and time. This could be done by adding a second read-only RichTextBox that has the InlineUIContainer and the already-bound control. This even works when cutting and pasting from other applications and does not require custom controls.
Another consideration is that the code to convert between FlowDocument and RTF is relatively complex so it may have lower performance than going with XAML. Of course loose XAML doesn't include images and such - for that you need to use XamlPackage. I store my XamlPackage in the database as a byte[], but you can also choose to Base64 encode it for storage as a string.
The bottom line is that it really depends on whether you want the user to be able to use features not available in RTF. Even if your application doesn't include tools to generate FlowDocuments that use these features, it is possible to cut-and-paste them from other applications.
Be aware that in Wpf RichTextBox's method called TextRange.Save has a bug whereby it loses any end of line terminator. Microsoft will not fix.
https://connect.microsoft.com/WPF/feedback/ViewFeedback.aspx?FeedbackID=478640&wa=wsignin1.0#tabs

How to create a shape acting like a textbox?

Please refer this control
http://www.charlespetzold.com/blog/2009/10/Using-Text-Outlines-in-Silverlight.html
The formattedtext control is a shape which helps to generate the shape of the text with proper geometry. I would like to make this control act like a text box with cursors and features like typing in from keyboard.
Right now I use an invisible text box with a formattedtext control to act like that. But the cursor position always creates a problem when the size of the text is not equal to the size of the rendered text as shape.
Can anyone please show the way to achieve this.
Well, I built a syntax highlighting textbox using the method you describes.
Actually, at first I wanted to rebuilt everything too, but I thought : I have to build the caret fonctionnalities, the selection brush, manage a lot of different events, like selection with mouse or keyboard, deletion, Copy/Cut/Paste, etc etc...
That's a LOT of work, and windows users are used to select text in textboxes for instance, so this complex implementation cannot be left unimplemented. We must follow some Microsoft guidance on how a textbox must feel.
Actually, I think that building a new textbox from scratch is not the way to go. I suggest you to continue on your current method. If you have different fonts in the same textbox, use a RichTextBox, and handle the font changes in the textbox as well as in the formatted text.
Also, a good think to implement is to only draw the visible text with the formattedtext (but only if the user can write several hundreds of text lines).

Resources