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

WinUI 3中TextBlock控件Text属性的自定义标签解析实现

WinUI3 TextBlock 动态解析自定义格式标签实现文本格式化

问题背景

我了解WinUI 3的TextBlock控件可通过C#代码与XAML标记实现文本格式设置(斜体、粗体、下划线等),MSDN官网的示例如下:

<TextBlock FontFamily="Arial">
    <Run Foreground="Blue" FontWeight="Light" Text="This text demonstrates "></Run>
    <Span FontWeight="SemiBold">
        <Run FontStyle="Italic">the use of inlines </Run>
        <Run Foreground="Red">with formatting.</Run>
    </Span>
</TextBlock>

但我的场景中,文本需在按钮点击时更新且数据量极大,无法通过XAML标记实现,也不能手动逐行编写C#代码处理。我预先准备的文本带有如下格式的标签:

"WinUI 3 {b}decouples{/b} WinRT XAML from the {i}operating system{/i} as a separate..."

这些标签此前在RenPy引擎中可被处理,我希望在WinUI 3中实现同样的动态标签解析与文本格式转换效果,也可更换标签格式。请问如何实现该功能?是否有替代方案?我曾考虑编写算法将标签内容包裹为Bold、Italic等类,但不知如何落地。

最终解决方案

以下是针对该问题的最终解决方案,感谢Andrew KeepCoding的提示:

解析文本生成Token方法

private List<string> Parsing(string text)
{
    List<string> tokens = new List<string>();
    Regex regex = new Regex(@"{[ibsu]}|{/[ibsu]}");
    MatchCollection matches = regex.Matches(text);
    int lastIndex = 0;

    foreach (Match match in matches.Cast<Match>())
    {
        if (match.Index > lastIndex)
        {
            tokens.Add(text[lastIndex..match.Index]);
        }

        tokens.Add(match.Value);
        lastIndex = match.Index + match.Length;
    }

    if (lastIndex < text.Length)
    {
        tokens.Add(text[lastIndex..]);
    }

    return tokens;
}

生成格式化文本并绑定到TextBlock方法

private void SetText(string text)
{
    Stack<Span> stack = new Stack<Span>();
    stack.Push(new Span());

    foreach (string token in Parsing(text))
    {
        switch (token)
        {
            case "{b}":
                stack.Push(new Bold());
                continue;
            case "{i}":
                stack.Push(new Italic());
                continue;
            case "{u}":
                stack.Push(new Underline());
                continue;
            case "{s}":
                stack.Push(new Span() { TextDecorations = TextDecorations.Strikethrough });
                continue;
            case "{/b}":
            case "{/i}":
            case "{/u}":
            case "{/s}":
                Span span = stack.Pop();
                stack.Peek().Inlines.Add(span);
                continue;
            default:
                break;
        }

        Run run = new Run() { Text = token };
        stack.Peek().Inlines.Add(run);
    }

    _TextBlock.Inlines.Add(stack.Pop());
}

内容的提问来源于stack exchange,提问作者Георгий Попов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:35:08