3

I am trying to get and set rich text in a ;RichEditBox, but every time I do perform a GetText then a SetText, one extra carriage return is added. Here the super simple example with a button that does get then set. Try it out to see one extra carriage return being added every time you perform the Get-Set.

XAML

<StackPanel>
    <Button Content="Get-Set" Click="OnGetSet"/>
    <RichEditBox x:Name="RichEditor" Width="300" Height="200"/>
</StackPanel>

C#

private void OnGetSet(object sender, RoutedEventArgs e)
{
    RichEditor.Document.GetText(TextGetOptions.FormatRtf, out value);
    RichEditor.Document.SetText(TextSetOptions.FormatRtf, value);
} 

I tried all sort of options both in the SetText and in the GetText, but I am able to prevent additional carriage return to be inserted. Does anyone have a suggestion?

Martin Zikmund
  • 38,440
  • 7
  • 70
  • 91
ClaudiaWey
  • 167
  • 9
  • I ended up finding a workaround, that I posted below. – ClaudiaWey Oct 07 '18 at 15:31
  • For information, and help people track a potential bug fix: the problem has been reported to the Microsoft team on their Github repository and can be followed there. See https://github.com/microsoft/microsoft-ui-xaml/issues/1941. – dgellow May 06 '21 at 15:35

3 Answers3

4

I ended up finding a reasonable workaround. I am getting the full range of text, then invoke the GetText on the range instead of the document.

I am not sure if this is the best solution, but it works fine.

Updated C#

private void OnGetSet(object sender, RoutedEventArgs e)
{
    var value = GetText(RichEditor);
    RichEditor.Document.SetText(TextSetOptions.FormatRtf, value);
}

public string GetText(RichEditBox editor)
{
    // get the actual size of the text
    editor.Document.GetText(TextGetOptions.UseLf, out string text);

    // get the text in the total range - to avoid getting extra lines
    var range = editor.Document.GetRange(0, text.Length);
    range.GetText(TextGetOptions.FormatRtf, out string value);

    // return the value
    return value;
}
ClaudiaWey
  • 167
  • 9
  • The issue for me with this code is that if a bullet list is the last thing in your document, the last bullet in the list will not be saved as a bullet. It will be saved like a normal sentence or whatever. I think this is a bug with the editor; more proof that Microsoft is just lazy in developing and debugging their tools. And years can go by before obvious bugs are discovered, and then more years before they finally say, "We fixed that issue" – LeBrown Jones Oct 21 '18 at 23:55
  • I can point out several bugs that have always existed with the RichEditBox. The control overall seems very dated to begin with, as if they were lazy and just imported some legacy code, and then cleaned up just enough to say, "Hey, we have something more than just a simple TextBox for you developers to work with." No wonder the UWP platform is not being adopted. Excuse me, but I just get annoyed easily when it comes to the millions of OBVIOUS issues that exist in UWP – LeBrown Jones Oct 21 '18 at 23:59
1

I found a solution for this that doesn't seem to conflict with lists and doesn't involve any sort of manual cleaning of the RTF text.

As seen in ClaudiaWey's answer, the length of the text is correct when getting the text in plain text format, at least when using LF. The problem only appears when getting the text in RTF.

So my solution was to store the non-RTF length alongside the RTF text content and then delete the difference between that length and the new (wrong) length when loading the RTF content back into the text box.

In code form, that looks something like this:

TextBox.TextDocument.GetText(TextGetOptions.FormatRtf, out string savedRichText);
TextBox.TextDocument.GetText(TextGetOptions.UseLf, out string savedText);
var savedLength = savedText.Length;

// persist savedLength to the database or wherever alongside savedRichText...

TextBox.TextDocument.SetText(TextSetOptions.FormatRtf, savedRichText);
// Delete the extra bit that gets added because of a bug
TextBox.TextDocument.GetText(TextGetOptions.UseLf, out string text);
TextBox.TextDocument.GetRange(savedLength, text.Length).Text = "";
audoh
  • 81
  • 9
0

In the meantime I found another workaround, but yours is much less hacky :-) . I just remove the last added newline:

RichEditor.Document.GetText(TextGetOptions.FormatRtf, out var value);
var lastNewLine = value.LastIndexOf("\\par", StringComparison.Ordinal);
value = value.Remove(lastNewLine, "\\par".Length);
RichEditor.Document.SetText(TextSetOptions.FormatRtf, value);            

But this depends on the "wrong" behavior of the RichEditBox, so your solution is much better.

Martin Zikmund
  • 38,440
  • 7
  • 70
  • 91