25 KiB
AtomUI 主题系统 — Design Token 四层架构详解
本文档详细描述 AtomUI Design Token 体系的四层架构设计,完整对应 Ant Design 5.0 的 Design Token 系统。
1. Token 四层推导链
Ant Design 5.0 将 Design Token 分解为三个全局层级加一个组件层级,AtomUI 完整实现了这一架构:
┌─────────────────────────────────────────────────────────────────────┐
│ 第 1 层:Seed Token(种子变量) │
│ 定义文件:DesignToken.Seed.cs │
│ 数量:约 20 个 │
│ 特征:设计意图的最小集合,修改一个即可全局级联 │
│ 示例:ColorPrimary, ColorSuccess, FontSize, BorderRadius │
│ Ant Design 对应:SeedToken interface │
└────────────────────────────┬────────────────────────────────────────┘
│
│ IThemeVariantCalculator.Calculate()
│ (主题算法自动推导)
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 第 2 层:Map Token(梯度变量) │
│ 定义文件:DesignToken.Color*Map.cs, DesignToken.FontMap.cs, │
│ DesignToken.SizeMap.cs, DesignToken.HeightMap.cs, │
│ DesignToken.StyleMap.cs, DesignToken.ColorNeutralMap.cs │
│ 数量:约 100+ 个 │
│ 特征:由 Seed Token 经算法系统派生的梯度序列 │
│ 示例:ColorPrimaryBg(1号色), ColorPrimaryHover(5号色), FontSizeLG │
│ Ant Design 对应:MapToken interface │
└────────────────────────────┬────────────────────────────────────────┘
│
│ DesignToken.CalculateAliasTokenValues()
│ (别名计算 — 直接赋值 / 透明度混合)
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 第 3 层:Alias Token(别名变量 / 语义变量) │
│ 定义文件:DesignToken.Alias.cs │
│ 数量:约 100+ 个 │
│ 特征:Map Token 的语义化封装,面向组件批量消费 │
│ 示例:ColorTextDisabled, ColorBgContainer, PaddingContentHorizontal │
│ Ant Design 对应:AliasToken interface │
└────────────────────────────┬────────────────────────────────────────┘
│
│ AbstractControlDesignToken.CalculateTokenValues()
│ (组件 Token 从 SharedToken 派生)
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 第 4 层:Component Token(组件变量) │
│ 定义文件:各组件的 *Token.cs(如 ButtonToken.cs, TagToken.cs) │
│ 数量:每个组件 5-30 个不等 │
│ 特征:组件专属 Token,从 SharedToken 派生,可被用户单独覆盖 │
│ 示例:ButtonToken.PrimaryColor, TagToken.DefaultBg │
│ Ant Design 对应:ComponentToken interface (theme.components.Button) │
└─────────────────────────────────────────────────────────────────────┘
关键概念:SharedToken
在 AtomUI 中,DesignToken 类(即 Ant Design 中 Seed + Map + Alias 的统一体)被称为 SharedToken。它是 Theme 级别的全局变量集,所有 Component Token 通过 SharedToken 属性访问全局 Token 值。
2. Seed Token 详解
2.1 定义方式
Seed Token 定义在 DesignToken.Seed.cs 中,使用 [DesignTokenKind(DesignTokenKind.Seed)] 标注:
[GlobalDesignToken]
public partial class DesignToken
{
[DesignTokenKind(DesignTokenKind.Seed)]
public Color ColorPrimary { get; set; } // 品牌主色 — #1677ff
[DesignTokenKind(DesignTokenKind.Seed)]
public Color ColorSuccess { get; set; } // 成功色 — #52c41a
[DesignTokenKind(DesignTokenKind.Seed)]
public double FontSize { get; set; } = 14; // 基础字号
[DesignTokenKind(DesignTokenKind.Seed)]
public CornerRadius BorderRadius { get; set; } // 基础圆角
[DesignTokenKind(DesignTokenKind.Seed)]
public double ControlHeight { get; set; } = 32; // 基础控件高度
[DesignTokenKind(DesignTokenKind.Seed)]
public bool EnableMotion { get; set; } = true; // 是否开启动画
// ... 更多 Seed Token
}
2.2 完整 Seed Token 列表
| Token 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ColorPrimary |
Color |
#1677ff |
品牌主色 |
ColorSuccess |
Color |
#52c41a |
成功色 |
ColorWarning |
Color |
#faad14 |
警戒色 |
ColorError |
Color |
#ff4d4f |
错误色 |
ColorInfo |
Color |
#1677ff |
信息色 |
ColorTextBase |
Color? |
null |
基础文本色(用于派生,不直接使用) |
ColorBgBase |
Color? |
null |
基础背景色(用于派生,不直接使用) |
ColorLink |
Color? |
null |
超链接颜色 |
ColorTransparent |
Color |
Transparent |
透明色 |
FontFamily |
FontFamily? |
Alibaba Sans 族 | 字体家族 |
FontSize |
double |
14 |
默认字号 |
LineWidth |
double |
1 |
基础线宽 |
LineType |
LineStyle |
Solid |
线条样式 |
BorderRadius |
CornerRadius |
6 |
基础圆角 |
SizeUnit |
double |
4 |
尺寸变化单位 |
SizeStep |
double |
4 |
尺寸步长 |
SizePopupArrow |
double |
16 |
弹出箭头大小 |
ControlHeight |
double |
32 |
基础控件高度 |
ZIndexBase |
int |
0 |
基础 z-index |
ZIndexPopupBase |
int |
1000 |
浮层 z-index |
OpacityImage |
double |
1.0 |
图片不透明度 |
MotionUnit |
int |
100 |
动画时长单位 (ms) |
MotionBase |
int |
0 |
动画基础时长 (ms) |
EnableMotion |
bool |
true |
是否开启动画 |
EnableWaveSpirit |
bool |
true |
是否开启波浪动画 |
2.3 设计意图
Seed Token 是整个 Token 体系的源头。用户只需修改极少数 Seed Token(典型场景只需改 ColorPrimary),算法就能自动派生出完整的 Map Token 和 Alias Token,保证设计一致性。
这与 Ant Design 官方文档中的说法一致:
"种子 Token 是主题中的一级变量,比如
colorPrimary、borderRadius。通过修改种子 Token 来自动生成 Map Token 和 Alias Token,进而影响所有使用到这些 Token 的组件。"
3. Map Token 详解
3.1 概述
Map Token 是由 Seed Token 通过主题算法自动推导的梯度变量。在 Ant Design 中,Map Token 形成了完整的色彩体系、尺寸体系、字体体系。
3.2 颜色梯度体系(10 号色系统)
每个功能色(Primary / Success / Warning / Error / Info)都从种子颜色自动生成 10 个梯度色,编号 1-10:
Seed Color (6号色)
│
├── PaletteGenerator.GeneratePalette()
│
▼
┌───────────────────────────────────────────────────────────┐
│ 1号色 浅色背景 ColorPrimaryBg (#e6f4ff) │
│ 2号色 浅色背景悬浮 ColorPrimaryBgHover (#bae0ff) │
│ 3号色 描边色 ColorPrimaryBorder (#91caff) │
│ 4号色 描边色悬浮 ColorPrimaryBorderHover(#69b1ff) │
│ 5号色 悬浮态 ColorPrimaryHover (#4096ff) │
│ 6号色 主色 ★ ColorPrimary (#1677ff) │
│ 7号色 激活态 ColorPrimaryActive (#0958d9) │
│ 8号色 文本悬浮态 ColorPrimaryTextHover (#4096ff) │
│ 9号色 文本色 ColorPrimaryText (#1677ff) │
│ 10号色 文本激活态 ColorPrimaryTextActive (#0958d9) │
└───────────────────────────────────────────────────────────┘
语义映射规则:
| 色号 | 语义 | 典型用途 |
|---|---|---|
| 1 号色 | *Bg |
选中状态的浅背景 |
| 2 号色 | *BgHover |
浅背景的悬浮态 |
| 3 号色 | *Border |
描边色 |
| 4 号色 | *BorderHover |
描边悬浮态 |
| 5 号色 | *Hover |
主色悬浮态 |
| 6 号色 | 主色 (= Seed) | 主按钮、主色调 |
| 7 号色 | *Active |
主色激活态(按下) |
| 8 号色 | *TextHover |
文本色悬浮态 |
| 9 号色 | *Text |
文本色 |
| 10 号色 | *TextActive |
文本色激活态 |
3.3 中性色体系
中性色不是从单一种子色派生,而是由 ColorBgBase(背景基色)和 ColorTextBase(文本基色)通过透明度/明度运算生成:
文本色梯度:
| Token | 亮色模式 | 暗色模式 |
|---|---|---|
ColorText |
rgba(0,0,0,0.88) | rgba(255,255,255,0.85) |
ColorTextSecondary |
rgba(0,0,0,0.65) | rgba(255,255,255,0.65) |
ColorTextTertiary |
rgba(0,0,0,0.45) | rgba(255,255,255,0.45) |
ColorTextQuaternary |
rgba(0,0,0,0.25) | rgba(255,255,255,0.25) |
填充色梯度:
| Token | 亮色模式 | 暗色模式 |
|---|---|---|
ColorFill |
rgba(0,0,0,0.15) | rgba(255,255,255,0.18) |
ColorFillSecondary |
rgba(0,0,0,0.06) | rgba(255,255,255,0.12) |
ColorFillTertiary |
rgba(0,0,0,0.04) | rgba(255,255,255,0.08) |
ColorFillQuaternary |
rgba(0,0,0,0.02) | rgba(255,255,255,0.04) |
背景色梯度:
| Token | 亮色模式 | 暗色模式 |
|---|---|---|
ColorBgLayout |
白色微暗(4%) | 纯黑 |
ColorBgContainer |
白色 | 黑色微亮(8%) |
ColorBgElevated |
白色 | 黑色微亮(12%) |
ColorBgSpotlight |
rgba(0,0,0,0.85) | 黑色微亮(26%) |
3.4 字体梯度
从 FontSize (Seed) 通过自然对数曲线函数 e^(i/5) 派生字体大小序列:
// CalculatorUtils.CalculateFontSize()
var baseSize = baseValue * Math.Pow(2.71828, i / 5.0);
生成的字体梯度:
| Token | 值 (FontSize=14 时) |
|---|---|
FontSizeSM |
12 |
FontSize |
14 (Seed) |
FontSizeLG |
16 |
FontSizeXL |
20 |
FontSizeHeading5 |
16 |
FontSizeHeading4 |
20 |
FontSizeHeading3 |
24 |
FontSizeHeading2 |
30 |
FontSizeHeading1 |
38 |
行高通过公式 (fontSize + 8) / fontSize 自动计算。
3.5 尺寸梯度
从 SizeUnit(4) 和 SizeStep(4) 派生:
// CalculatorUtils.CalculateSizeMapTokenValues()
designToken.SizeXXL = sizeUnit * (sizeStep + 8); // 48
designToken.SizeXL = sizeUnit * (sizeStep + 4); // 32
designToken.SizeLG = sizeUnit * (sizeStep + 2); // 24
designToken.SizeMD = sizeUnit * (sizeStep + 1); // 20
designToken.Size = sizeUnit * sizeStep; // 16
designToken.SizeSM = sizeUnit * (sizeStep - 1); // 12
designToken.SizeXS = sizeUnit * (sizeStep - 2); // 8
designToken.SizeXXS = sizeUnit * (sizeStep - 3); // 4
3.6 控件高度梯度
从 ControlHeight(32) 通过比例派生:
designToken.ControlHeightSM = controlHeight * 0.75; // 24
designToken.ControlHeightXS = controlHeight * 0.5; // 16
designToken.ControlHeightLG = controlHeight * 1.25; // 40
3.7 样式梯度
包含圆角梯度、线宽梯度、动效时长梯度:
// 动效时长
designToken.MotionDurationFast = motionBase + motionUnit; // 100ms
designToken.MotionDurationMid = motionBase + motionUnit * 2; // 200ms
designToken.MotionDurationSlow = motionBase + motionUnit * 3; // 300ms
designToken.MotionDurationVerySlow = motionBase + motionUnit * 8; // 800ms
// 圆角 (基于 BorderRadius=6 的 LUT)
designToken.BorderRadiusXS = 2; // 最小圆角
designToken.BorderRadiusSM = 4; // 小圆角
designToken.BorderRadius = 6; // 基础圆角 (Seed)
designToken.BorderRadiusLG = 8; // 大圆角
designToken.BorderRadiusOuter = 4; // 外部圆角
4. Alias Token 详解
4.1 概述
Alias Token 是 Map Token 的语义化封装。它们不引入新的计算逻辑,而是将 Map Token 赋予更具业务含义的名称,便于组件批量消费。
计算逻辑在 DesignToken.CalculateAliasTokenValues() 中:
internal void CalculateAliasTokenValues()
{
// 背景相关
ColorFillContent = ColorFillSecondary;
ColorFillContentHover = ColorFill;
ColorBgContainerDisabled = ColorFillTertiary;
// 文本相关
ColorTextPlaceholder = ColorTextQuaternary;
ColorTextDisabled = ColorTextQuaternary;
ColorTextHeading = ColorText;
ColorTextLabel = ColorTextSecondary;
ColorTextDescription = ColorTextTertiary;
// 控件交互
ControlItemBgHover = ColorFillTertiary;
ControlItemBgActive = ColorPrimaryBg;
ControlItemBgActiveHover = ColorPrimaryBgHover;
// 间距 (从 Size 梯度映射到 Padding/Margin/Spacing)
PaddingContentHorizontal = SizeMS;
PaddingContentVertical = SizeSM;
...
}
4.2 Alias Token 分类
4.2.1 语义颜色
| Token | 来源 | 语义 |
|---|---|---|
ColorTextPlaceholder |
ColorTextQuaternary |
占位文本颜色 |
ColorTextDisabled |
ColorTextQuaternary |
禁用文本颜色 |
ColorTextHeading |
ColorText |
标题文本颜色 |
ColorTextLabel |
ColorTextSecondary |
标签文本颜色 |
ColorTextDescription |
ColorTextTertiary |
描述文本颜色 |
ColorTextLightSolid |
ColorWhite |
深色背景上的文本 |
ColorHighlight |
ColorError |
高亮颜色 |
ColorIcon |
ColorTextTertiary |
弱操作图标颜色 |
ColorIconHover |
ColorText |
图标悬浮色 |
ColorBgContainerDisabled |
ColorFillTertiary |
禁用容器背景 |
ColorSplit |
混合计算 | 分割线颜色 |
ColorControlOutline |
混合计算 | 输入组件外轮廓 |
ColorErrorOutline |
混合计算 | 错误状态外轮廓 |
ColorWarningOutline |
混合计算 | 警告状态外轮廓 |
4.2.2 间距与布局
| Token | 来源 | 语义 |
|---|---|---|
PaddingXXS ~ PaddingXL |
SizeXXS ~ SizeXL |
内间距梯度(Thickness) |
UniformlyPaddingXXS ~ UniformlyPaddingXL |
SizeXXS ~ SizeXL |
统一内间距(double) |
MarginXXS ~ MarginXXL |
SizeXXS ~ SizeXXL |
外边距梯度 |
SpacingXXS ~ SpacingXXL |
SizeXXS ~ SizeXXL |
布局间距梯度 |
PaddingContentHorizontal* |
SizeMS / SizeSM / SizeLG |
内容区水平内间距 |
PaddingContentVertical* |
SizeSM / SizeXS / SizeMS |
内容区垂直内间距 |
4.2.3 控件交互
| Token | 来源 | 语义 |
|---|---|---|
ControlItemBgHover |
ColorFillTertiary |
列表项悬浮背景 |
ControlItemBgActive |
ColorPrimaryBg |
列表项选中背景 |
ControlItemBgActiveHover |
ColorPrimaryBgHover |
选中项悬浮背景 |
ControlItemBgActiveDisabled |
ColorFill |
禁用选中项背景 |
ControlInteractiveSize |
ControlHeight / 2 |
控件交互区大小 |
ControlOutlineWidth |
LineWidth * 2 |
外轮廓线宽 |
LineWidthFocus |
LineWidth * 2 |
聚焦态线宽 |
4.2.4 阴影
| Token | 说明 |
|---|---|
BoxShadows |
一级阴影(3 层复合阴影) |
BoxShadowsSecondary |
二级阴影 |
BoxShadowsTertiary |
三级阴影 |
4.2.5 响应式断点
| Token | 值 |
|---|---|
ScreenXS |
480px |
ScreenSM |
576px |
ScreenMD |
768px |
ScreenLG |
992px |
ScreenXL |
1200px |
ScreenXXL |
1600px |
5. Component Token 详解
5.1 定义规范
每个控件有自己的 Token 类,继承 AbstractControlDesignToken:
[ControlDesignToken]
internal class ButtonToken : AbstractControlDesignToken
{
// 必须有 const string ID
public const string ID = "Button";
// 必须有 static readonly ScopeProvider
public static readonly ControlTokenResourceScopeProvider ScopeProvider = new(ID);
/// <summary>
/// 主要按钮文本颜色
/// </summary>
public Color PrimaryColor { get; set; }
/// <summary>
/// 按钮内间距
/// </summary>
public Thickness Padding { get; set; }
// 构造函数必须调用 base(ID)
public ButtonToken() : base(ID) { }
// 从 SharedToken 派生所有值 — 禁止硬编码
public override void CalculateTokenValues(bool isDarkMode)
{
base.CalculateTokenValues(isDarkMode);
PrimaryColor = SharedToken.ColorTextLightSolid;
Padding = new Thickness(
SharedToken.PaddingContentHorizontal - SharedToken.LineWidth, 0);
}
// 返回 Source Generator 生成的 TokenKind 枚举类型
protected override Type GetTokenKindType() => typeof(ButtonTokenKind);
}
5.2 Component Token 的 SharedToken 覆盖机制
Ant Design 5.0 允许为某个组件单独修改全局 Token,这在 AtomUI 中通过以下机制实现:
- 默认情况:组件的
SharedToken指向全局的DesignToken实例。 - 有组件级配置时:
- 克隆一份全局
DesignToken:var copiedSharedToken = (DesignToken)_sharedToken.Clone() - 在克隆副本上应用组件级的 Seed/Map/Alias 覆盖
- 如果
EnableAlgorithm = true,重新运行算法推导 - 将修改后的副本赋给组件 Token:
controlToken.AssignSharedToken(copiedSharedToken)
- 克隆一份全局
- 差值字典:
BuildSharedResourceDeltaDictionary()计算组件级 SharedToken 与全局 SharedToken 的差异,生成差值ResourceDictionary,在控件级别通过ControlTokenResourceScopeHost注入。
这完整对应了 Ant Design 中 theme.components.Button = { colorPrimary: '#xxx' } 的能力。
5.3 Token 值类型转换
从 XML/XAML 配置加载的 Token 值是字符串,需要转换为 C# 类型。BuiltInTokenValueConverters.cs 提供了内置转换器:
| 转换器 | 目标类型 |
|---|---|
StringTokenValueConverter |
string |
IntegerTokenValueConverter |
int |
DoubleTokenValueConverter |
double |
FloatTokenValueConverter |
float |
BoolTokenValueConverter |
bool |
ColorTokenValueConverter |
Color |
BoxShadowTokenValueConverter |
BoxShadows |
TextDecorationTokenValueConverter |
TextDecorationInfo |
LineStyleTokenValueConverter |
LineStyle |
ThicknessTokenValueConverter |
Thickness |
CornerRadiusTokenValueConverter |
CornerRadius |
转换器通过 [TokenValueConverter] 标注自动发现和注册。
6. Token 标注系统
6.1 Attribute 定义
| Attribute | 目标 | 作用 |
|---|---|---|
[GlobalDesignToken] |
DesignToken partial class |
标记为全局 Token 定义(Source Generator 识别) |
[ControlDesignToken] |
组件 Token 类 | 标记为组件 Token(Source Generator 识别) |
[DesignTokenKind(kind)] |
Token 属性 | 标注 Token 所属层级(Seed/Map/Alias) |
[NotTokenDefinition] |
属性 | 排除不是 Token 的属性 |
[TokenValueConverter] |
转换器类 | 标记 Token 值转换器 |
6.2 Source Generator 生成物
AtomUI.Generator 中的 TokenResourceKeyGenerator 会扫描所有标注了 [GlobalDesignToken] 和 [ControlDesignToken] 的类,自动生成:
SharedTokenKind枚举 — 全局 Token 的资源键枚举{Control}TokenKind枚举 — 每个组件 Token 的资源键枚举ControlTokenTypePool类 — 所有组件 Token 类型的注册池
这些生成的枚举作为 ResourceDictionary 的键,确保 Token 访问的编译期类型安全。
7. Token 推导完整流程
以一个主题加载为例,完整的 Token 推导流程如下:
Theme.BuildThemeResource()
│
├── 1. 初始化 DesignToken(Seed Token 默认值)
│ ColorPrimary = #1677ff, FontSize = 14, ...
│
├── 2. 从 XML 加载用户自定义 Seed Token 覆盖
│ _sharedToken.LoadConfig(seedTokenConfig)
│ // 用户可能覆盖 ColorPrimary = #ff0000
│
├── 3. 主题算法计算 Map Token
│ calculator.Calculate(_sharedToken)
│ ├── PaletteGenerator.GeneratePalette(ColorPrimary)
│ │ → 生成主色 10 级色阶
│ ├── 同理生成 Success/Warning/Error/Info 色阶
│ ├── CalculateNeutralColorPalettes() → 中性色体系
│ ├── CalculateFontMapTokenValues() → 字体梯度
│ ├── CalculateSizeMapTokenValues() → 尺寸梯度
│ ├── CalculateControlHeightMapTokenValues() → 高度梯度
│ └── CalculateStyleMapTokenValues() → 圆角/动效梯度
│
├── 4. 从 XML 加载用户自定义 Map Token 覆盖
│ _sharedToken.LoadConfig(mapTokenConfig)
│
├── 5. 计算 Alias Token
│ _sharedToken.CalculateAliasTokenValues()
│ // ColorTextDisabled = ColorTextQuaternary, ...
│
├── 6. 从 XML 加载用户自定义 Alias Token 覆盖
│ _sharedToken.LoadConfig(aliasTokenConfig)
│
├── 7. SharedToken 写入 ResourceDictionary
│ _sharedToken.BuildResourceDictionary(ResourceDictionary)
│
├── 8. 收集所有注册的 ControlToken 类型,实例化
│ CollectControlTokens()
│
├── 9. 为每个 ControlToken 分配 SharedToken
│ ├── 无组件级配置 → 直接使用全局 SharedToken
│ └── 有组件级配置 → 克隆 SharedToken → 应用覆盖 → 可选重新算法推导
│
├── 10. 计算每个 ControlToken 的值
│ controlToken.CalculateTokenValues(isDarkMode)
│
├── 11. 从 XML 加载用户自定义 ControlToken 覆盖
│ controlToken.LoadConfig(componentTokenConfig)
│
├── 12. ControlToken 写入 ResourceDictionary
│ controlToken.BuildResourceDictionary(ResourceDictionary)
│
└── 13. 有组件级配置的 ControlToken,构建差值字典
controlToken.BuildSharedResourceDeltaDictionary()
8. 与 Ant Design 的 Token 使用方式对比
Ant Design (React)
<ConfigProvider
theme={{
token: {
colorPrimary: '#00b96b', // 修改 Seed Token
borderRadius: 2,
},
components: {
Button: {
colorPrimary: '#ff0000', // 组件级 Token 覆盖
algorithm: true, // 启用算法重新派生
},
},
}}
>
<App />
</ConfigProvider>
AtomUI (C# / XAML)
方式一:XML 主题定义文件
<Theme Name="Custom" IsDefault="true">
<SharedTokens>
<Token Name="ColorPrimary" Value="#00b96b" />
<Token Name="BorderRadius" Value="2" />
</SharedTokens>
<ControlTokens>
<ControlToken Id="Button" EnableAlgorithm="true">
<Token Name="ColorPrimary" Value="#ff0000" IsShared="true" />
</ControlToken>
</ControlTokens>
</Theme>
方式二:XAML ThemeConfigProvider
<atom:ThemeConfigProvider>
<atom:ThemeConfigProvider.SharedTokenSetters>
<atom:TokenSetter Key="ColorPrimary" Value="#00b96b" />
</atom:ThemeConfigProvider.SharedTokenSetters>
<atom:ThemeConfigProvider.ControlTokenInfoSetters>
<atom:ControlTokenInfoSetter TokenId="Button" EnableAlgorithm="True">
<atom:TokenSetter Key="ColorPrimary" Value="#ff0000" />
</atom:ControlTokenInfoSetter>
</atom:ThemeConfigProvider.ControlTokenInfoSetters>
<StackPanel><!-- 子控件受此配置影响 --></StackPanel>
</atom:ThemeConfigProvider>