【问题标题】:WPF RichTextBox Rtf property wrong converting non ascii charsWPF RichTextBox Rtf 属性错误转换非 ascii 字符
【发布时间】:2021-01-15 13:19:33
【问题描述】:

NET Core 版本:3.1.405 Windows 版本:Windows 10

RichTextBox 无法从我的 WPF 应用程序中的 rtf 字符串转换非 ascii 字符。

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

实际行为:我的 RichTextbox 显示“Entête”。 “ê”(非 ASCII 字符)的转换问题

预期行为:我的 RichTextbox 显示“Entête”。 “ê”的转换问题

【问题讨论】:

  • 我似乎您的 RTF 字符串不符合标准的 RTF。如果你用这个{\ltrch Ent\'eate} 替换{\ltrch entête} 片段,非Unicode 字符将正确显示。非 ASCII 字符必须转义!
  • 它适用于 .NetFramework 4.6.1
  • 只是出于兴趣,我将您的代码放入 .NET Framework 4.6.1 中,因为它正在显示 entête。因此,您应该检查您的 RTF 字符串是如何从原始源创建的过程。

标签: c# wpf .net-core richtextbox


【解决方案1】:

上面代码中的RTF 字符串不符合标准的RTF。 非ASCII字符必须转义!如果用{\ltrch Ent\'eate}替换{\ltrch entête}片段,非Unicode字符将正确显示。

在某些情况下,可以假设不同程序或不同版本的程序创建的RTF文档可能不同:出现版本不兼容。

/// <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();
}

有关更多信息,请参阅:

【讨论】:

  • 不可能用这个 {\ltrch Entête} 片段替换 {\ltrch Ent\'eate} 因为我们有一个翻译过程
  • 哦,我明白了。这是个问题。由于在不同的帖子中,当出现版本不兼容的问题时,微软支持人员建议将文档加载到RithTextBox控件中,必要时更正文档,然后将其保存回文档。此后,当下次加载文档时,它将正确显示。
  • 或者您可以在将文档加载到RithTextBox 控件之前尝试通过在您的应用程序中替换字符(如ê\'e)来解决此问题。以下帖子描述了如何为此目的使用StringBuilderhttps://stackoverflow.com/a/1321343/6630084
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 2010-10-31
  • 1970-01-01
  • 2014-10-21
  • 1970-01-01
  • 2014-12-06
相关资源
最近更新 更多