简体   繁体   中英

WPF RichTextBox Rtf property wrong converting non ascii chars

NET Core Version: 3.1.405 Windows version: Windows 10

The RichTextBox cannot convert non ascii chars from my rtf string in my WPF application.

string rtf ="{\\rtf1\\ansi\\ansicpg1252\\uc1\\htmautsp\\deff2{\\fonttbl{\\f0\\fcharset0 Times New Roman;}{\\f2\\fcharset0 Arial;}}                                                     {\\colortbl\\red0\\green0\\blue0;\\red255\\green255\\blue255;}\\loch\\hich\\dbch\\pard\\plain\\ltrpar\\itap0{\\lang32\\fs30\\f2\\cf0 \\cf0\\qj\\sl15\\slmult0{\\f2 {\\ltrch entête}\\li0\\ri0\\sa0\\sb0\\fi0\\qj\\sl15\\slmult0\\par}}}"

if (rtf.Length > 2)
{
    FlowDocument flowDocument = new FlowDocument
    {
        LineHeight = 1,
        Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentUICulture.Name),                            
    };

    using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(rtf)))
    {
      TextRange text = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);

      if (stream.Length != 0)
      {
         text.Load(stream, DataFormats.Rtf);
      }

      text.ClearAllProperties();
    }

    return flowDocument;
}

Actual behavior: My RichTextbox display "Entête ". Problem with the conversion of "ê" (non ASCII chars)

Expected behavior: My RichTextbox display "Entête ". Problem with the conversion of "ê"

The RTF string from code above does not standard-compliant RTF. The non-ASCII characters must be escaped! If replace the {\ltrch entête} fragment by this one {\ltrch Ent\'eate} the non-Unicode character will be displayed correctly.

In some cases, it can be assumed that the RTF documents created by different programs, or different versions of programs, may be different: to occurs a version incompatibility.

/// <summary>
/// This method loads the `rtf` string to the `rtb` RichTextBox control. Before loading any non ASCII characters is converting to escaped.
/// </summary>
/// <param name="rtb">The RichTextBox control to which the RTF-string will be loaded</param>
/// <param name="rtf">The RTF-string that will be loaded to the RichTextBox control. The string can contain non-ASCII characters.</param>

public void LoadRtfString(RichTextBox rtb, string rtf)
{
    var flowDocument = new FlowDocument
    {
        LineHeight = 1,
        Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentUICulture.Name),
    };

    using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(ConvertNonAsciiToEscaped(rtf))))
    {
        var text = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
        text.ClearAllProperties();
        if (stream.Length != 0)
        {
            text.Load(stream, DataFormats.Rtf);
        }
    }
    rtb.Document = flowDocument;   
}

/// <param name="rtf">An RTF string that can contain non-ASCII characters and should be converted to correct format before loading to the RichTextBox control.</param>
/// <returns>The source RTF string with converted non ASCII to escaped characters.</returns>

public string ConvertNonAsciiToEscaped(string rtf)
{
    var sb = new StringBuilder();
    foreach (var c in rtf)
    {
        if (c <= 0x7f)
            sb.Append(c);
        else
            sb.Append("\\u" + Convert.ToUInt32(c) + "?");
    }
    return sb.ToString();
}

For additional information see:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM