在 Avalonia 开发中,我们常需在 XAML 的属性(如 Tag、ToolTip)中内嵌复杂字符串。若字符串包含双引号、尖括号等特殊字符,直接编写会导致 XAML 解析错误。本文将分享一种利用 x:String 与 <![CDATA[]]> 实现“所见即所得”内嵌的实用技巧。
痛点:特殊字符的转义难题
XAML 擅长描述 UI,但对内嵌复杂字符串的支持有限。例如,以下写法会因 < 和 " 被解析为标记而报错:
<Button Tag="<PathIcon Data=\"{DynamicResource $key$}\" Theme=\"{DynamicResource InnerPathIcon}\" />" />
虽然可通过 <、" 等实体编码解决,但代码会变得冗长、难以阅读和维护。
解决方案:x:String + CDATA
XAML 提供了 x:String 类型与 CDATA 块,二者结合可完美内嵌任意复杂度的字符串,且保持内容原貌。
示例:在 Button.Tag 中嵌入 XAML 片段
<StackPanel Classes="HorizontalTight">
<PathIcon Data="{Binding Geometry}" Theme="{DynamicResource InnerPathIcon}" />
<Button Classes="Small">
<Button.Tag>
<!-- 使用 x:String 明确类型 -->
<x:String>
<!-- CDATA 块确保内容不被解析 -->
<![CDATA[<PathIcon Data="{DynamicResource $key$}" Theme="{DynamicResource InnerPathIcon}" />]]>
</x:String>
</Button.Tag>
复制代码
</Button>
</StackPanel>
关键点解析
<Button.Tag>:Avalonia 属性,可承载任意对象,此处用于存储字符串。<x:String>:指定内容类型为字符串(需确保xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"已在根节点声明)。<![CDATA[ ... ]]>:包裹内容后,解析器会将其视为纯文本,忽略其中的所有特殊字符(如<、"、{}),实现“所见即所得”。
适用场景
- 代码示例界面:需在 UI 中展示或复制 XAML、JSON、XML 片段时。
- 模板编辑器:将动态生成的 XAML 代码片段暂存于属性中。
- 任何需在属性中存储富文本或标记语言的场景。
总结
x:String 配合 CDATA 是 Avalonia(及 WPF、UWP 等 XAML 技术栈)中内嵌复杂字符串的优雅方案。它避免了繁琐的转义,极大提升了代码的可读性和可维护性。






