You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用RichEditBox遇性能与存储问题,求简单格式化文本存储展示方案

解决大量简单格式化文本展示的性能与存储问题

嘿,看来你被大量RichEditBox的性能和存储问题坑到了!正好我之前处理过类似的场景,给你两个超实用的极简方案,完美适配你只需要粗体、斜体的需求:

方案一:Markdown存储 + TextBlock自定义渲染

RTF格式本身冗余度极高,光是简单的粗体文本都会生成一堆额外标记,这直接导致了你的存储占用过高。而Markdown的标记(**粗体**、*斜体*)非常简洁,存储体积能比RTF小80%以上。

同时,RichEditBox是为编辑场景设计的,每个实例都带着大量编辑相关的逻辑和状态开销,大量创建时性能必然拉胯。换成轻量级的TextBlock专门做展示,性能会提升一大截。

你只需要写个超简单的解析器(因为只有粗体斜体,完全不用复杂库),把Markdown字符串转成TextBlock的内联元素:

private TextBlock RenderSimpleMarkdown(string markdownContent)
{
    var textBlock = new TextBlock { TextWrapping = TextWrapping.Wrap };
    var segments = markdownContent.Split(new[] { "**", "*" }, StringSplitOptions.RemoveEmptyEntries);
    bool expectBold = false;
    bool expectItalic = false;

    foreach (var segment in segments)
    {
        var run = new Run(segment);
        
        if (expectBold)
        {
            run.FontWeight = FontWeights.Bold;
            expectBold = false;
        }
        else if (expectItalic)
        {
            run.FontStyle = FontStyles.Italic;
            expectItalic = false;
        }
        else
        {
            // 判断下一个标记类型
            var currentIndex = markdownContent.IndexOf(segment);
            if (currentIndex + segment.Length < markdownContent.Length)
            {
                var nextChar = markdownContent[currentIndex + segment.Length];
                if (nextChar == '*' && currentIndex + segment.Length +1 < markdownContent.Length 
                    && markdownContent[currentIndex + segment.Length +1] == '*')
                {
                    expectBold = true;
                }
                else if (nextChar == '*')
                {
                    expectItalic = true;
                }
            }
        }
        
        textBlock.Inlines.Add(run);
    }

    return textBlock;
}

优点:

  • 存储体积极小,数据库压力骤降
  • TextBlock性能远优于RichEditBox,大量实例化也不会卡顿
  • Markdown格式易读,手动修改或调试都方便

方案二:XAML内联片段存储 + TextBlock渲染

如果你不想自己写解析逻辑,也可以直接存储简化的XAML内联元素代码,比如:
<Run FontWeight="Bold">这是粗体</Run><Run FontStyle="Italic">这是斜体</Run>

然后用XAML原生解析器加载到TextBlock中:

private TextBlock RenderInlineXaml(string xamlSegments)
{
    var textBlock = new TextBlock { TextWrapping = TextWrapping.Wrap };
    var inlineCollection = (InlineCollection)System.Windows.Markup.XamlReader.Parse(
        $"<InlineCollection xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">{xamlSegments}</InlineCollection>"
    );

    foreach (var inline in inlineCollection)
    {
        textBlock.Inlines.Add(inline);
    }

    return textBlock;
}

优点:

  • 完全不用自己写解析逻辑,依赖原生XAML解析,稳定性高
  • 格式扩展灵活,以后要加颜色、下划线之类的简单格式,直接修改XAML片段就行

为什么这两个方案比RichEditBox好?

RichEditBox本质是一个富文本编辑器,它要处理光标、选中、编辑历史、格式工具栏交互等一堆你完全不需要的功能,每个实例的内存占用和初始化开销都远大于纯展示用的TextBlock。换成TextBlock后,UI线程的负载会直接降下来,滚动大量文本块也不会卡顿。

而存储上,不管是Markdown还是XAML片段,都比RTF精简太多——比如同样一句"Hello World",RTF会生成几十行冗余代码,而Markdown只有13个字符,XAML片段也才几十字节。

内容的提问来源于stack exchange,提问作者Tom Lux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:56:46