# Semi Avalonia Theme

> Semi.Avalonia theming guide covering theme setup, ControlTheme variants, style classes, and DynamicResource override patterns for light/dark themes.

- Skill: `irihitech/semi-avalonia-theme` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add irihitech/semi-avalonia-theme`
- Raw SKILL.md: https://api.skillmd.com/api/skills/irihitech/semi-avalonia-theme/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: irihitech (https://skillmd.com/u/irihitech)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/irihitech/semi-avalonia-theme

---


# Semi.Avalonia Theme / Semi.Avalonia 主题

Use this skill when working with Semi.Avalonia's theming system — setting up themes,
applying ControlTheme variants, using style classes, and overriding DynamicResource
values for customization.

在使用 Semi.Avalonia 主题系统时加载此 Skill —— 包括设置主题、应用 ControlTheme 变体、
使用样式类和通过覆写 DynamicResource 值进行自定义。

## Theme Setup / 主题设置

### RequestedThemeVariant / 请求主题变体

Semi.Avalonia provides Light and Dark themes. Set via `Application.RequestedThemeVariant`:

Semi.Avalonia 提供亮色（Light）和暗色（Dark）两种主题。通过 `Application.RequestedThemeVariant` 设置：

```xml
<Application xmlns:semi="https://irihi.tech/semi"
             RequestedThemeVariant="Light">  <!-- Light, Dark, or Default -->
    <Application.Styles>
        <semi:SemiTheme />
    </Application.Styles>
</Application>
```

| Value / 值 | Behavior / 行为 |
|---|---|
| `Light` | Always light theme. / 始终亮色。 |
| `Dark` | Always dark theme. / 始终暗色。 |
| `Default` | Follows system color preference. / 跟随系统颜色偏好。 |

### Locale / 语言设置

Avalonia built-in controls contain text (e.g., TextBox context menu). Set locale on `SemiTheme`:

Avalonia 内置控件包含文本（如 TextBox 右键菜单）。在 `SemiTheme` 上设置语言：

```xml
<Application.Styles>
    <semi:SemiTheme Locale="zh-CN" /> 
</Application.Styles>
```

## ControlTheme Variants / 控件主题变体

Semi.Avalonia provides default ControlThemes for all built-in Avalonia controls.
Additional special ControlThemes are available for some controls — applied via
the `Theme` attached property. They change the visual appearance while preserving
functionality.

Semi.Avalonia 为所有内置 Avalonia 控件提供了默认 ControlTheme。部分控件还提供了
额外的特殊 ControlTheme —— 通过 `Theme` 附加属性应用。它们改变视觉外观但保持功能不变。

### ProgressRing Example / ProgressRing 示例

Avalonia has a progress bar but no built-in progress ring. Semi.Avalonia provides one:

Avalonia 有进度条但无内置进度环。Semi.Avalonia 提供了进度环：

```xml
<ProgressBar Width="60" Height="60"
             Value="50"
             Theme="{DynamicResource ProgressRing}" />
```

### How to Apply / 使用方式

```xml
<!-- Apply a special ControlTheme -->
<ProgressBar Theme="{DynamicResource ProgressRing}" />

<!-- Button theme variants -->
<Button Theme="{DynamicResource SolidButton}" Content="Solid" />
<Button Theme="{DynamicResource OutlineButton}" Content="Outline" />
```

For a complete list of special ControlThemes per control, see the individual
[control references](../controls/reference/).

各控件完整的特殊 ControlTheme 列表参见独立的[控件参考](../controls/reference/)。

## Style Classes / 样式类

Style classes modify a control's appearance within its current theme. They are
applied via the `Classes` attached property. Multiple classes can be combined.

样式类在控件当前主题内修改其外观。通过 `Classes` 附加属性应用，可组合多个类。

### Color Classes / 颜色类

```xml
<!-- Warning (amber) button -->
<Button Classes="Warning" Content="Warning" />

<!-- Danger (red) button -->
<Button Classes="Danger" Content="Delete" />

<!-- Success (green) button -->
<Button Classes="Success" Content="Save" />
```

### Size Classes / 尺寸类

```xml
<Button Classes="Large" Content="Large Button" />
<Button Classes="Small" Content="Small Button" />
```

### Behavioral Classes / 行为类

```xml
<!-- Shows a clear (×) button on hover/focus in TextBox -->
<TextBox Classes="clearButton" />

<!-- TreeComboBox with clear button -->
<u:TreeComboBox Classes="clearButton" />
```

## Resource Customization / 资源自定义

### Basic Override / 基本覆写

Semi.Avalonia references most styling values (brushes, sizes, corner radii) as
`DynamicResource` keys. To customize globally, override the key in `App.axaml`.

Semi.Avalonia 中大多数样式值（笔刷、尺寸、圆角）以 `DynamicResource` 键引用。
要全局自定义，在 `App.axaml` 中覆写该键。

**Example: Change all Button corner radii from 3 to 6:**

**示例：将所有 Button 圆角从 3 改为 6：**

Source shows the key (`/src/Semi.Avalonia/Themes/Shared/Button.axaml`):

源码中可以看到该键的定义：

```xml
<CornerRadius x:Key="ButtonCornerRadius">3</CornerRadius>
```

Override in `App.axaml`:

在 `App.axaml` 中覆写：

```xml
<Application.Resources>
    <CornerRadius x:Key="ButtonCornerRadius">6</CornerRadius>
</Application.Resources>
```

### How to Find Resource Keys / 如何查找资源键

1. Check the control's AXAML theme file: `/src/Semi.Avalonia/Controls/{Control}.axaml`
   to see which `DynamicResource` keys the control uses.

   查看控件的 AXAML 主题文件，了解控件使用了哪些 `DynamicResource` 键。

2. Check `/src/Semi.Avalonia/Themes/Shared/{Control}.axaml` for the key **definition**.

   在 shared 主题文件中查看键的**定义**。

3. For control-specific keys, see the `DynamicResource Keys` section in each
   [control reference](../controls/reference/).

   控件专属键参见各[控件参考](../controls/reference/)的 `DynamicResource Keys` 部分。

### Theme-Aware Color Overrides / 主题感知颜色覆写

Color resources (brushes) may differ between Light and Dark themes. Override
per-theme using theme-specific resource dictionaries.

色彩资源（笔刷）在亮色和暗色主题下可能不同。使用主题特定的资源字典按主题覆写。

**Example: Change Button foreground to purple with Light/Dark variants:**

**示例：将 Button 前景色改为紫色，亮色/暗色各不同：**

Source shows the key in Light/Dark themes:

源码在亮色/暗色主题中分别定义：

```xml
<!-- Light: /src/Semi.Avalonia/Themes/Light/Button.axaml -->
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#0077FA" />

<!-- Dark: /src/Semi.Avalonia/Themes/Dark/Button.axaml -->
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#54A9FF" />
```

Override in `App.axaml`:

```xml
<Application>
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <!-- Light theme -->
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="ButtonDefaultPrimaryForeground"
                                     Color="#9E28B3" />
                </ResourceDictionary>
                <!-- Dark theme -->
                <ResourceDictionary x:Key="Dark">
                    <SolidColorBrush x:Key="ButtonDefaultPrimaryForeground"
                                     Color="#B553C2" />
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
```

## Common Patterns / 常用模式

### Quick color tweak / 快速颜色调整

Override a single brush in `Application.Resources` without theme dictionaries
(applies to both Light and Dark):

```xml
<Application.Resources>
    <SolidColorBrush x:Key="ButtonSolidPrimaryBackground" Color="#0050B3" />
</Application.Resources>
```

### Apply ControlTheme + Style Class Together / 同时应用 ControlTheme 和样式类

```xml
<Button Theme="{DynamicResource SolidButton}"
        Classes="Danger Large"
        Content="Delete" />
```

### Theme Variant Scope / 主题变体作用域

Use `ThemeVariantScope` to apply a different theme to a specific subtree:

```xml
<Panel>
    <!-- Default (Light) themed section -->
    <Button Content="Light Button" />
    
    <ThemeVariantScope RequestedThemeVariant="Dark">
        <!-- Dark themed section -->
        <Button Content="Dark Button" />
    </ThemeVariantScope>
</Panel>
```

## Authoring New Controls / 编写新控件

When creating a new Semi.Avalonia control or custom theme, always reference base
tokens rather than hardcoding values. This ensures theme consistency and
automatic Light/Dark support.

编写新的 Semi.Avalonia 控件或自定义主题时，始终引用基础令牌而非硬编码值。

### Step 1: Use Base Tokens Directly / 直接使用基础令牌

```xml
<!-- ✅ Good -->
<Setter Property="Height" Value="{DynamicResource SemiHeightControlDefault}" />
<Setter Property="CornerRadius" Value="{DynamicResource SemiBorderRadiusMedium}" />

<!-- ❌ Bad: hardcoded -->
<Setter Property="Height" Value="32" />
```

### Step 2: Create Semantic Aliases / 创建语义别名

Use `StaticResource` with `ResourceKey` to alias a base token without copying values:

```xml
<!-- ✅ Good -->
<StaticResource x:Key="AdornerLayerSolidBorderBrush"
                ResourceKey="SemiColorText0" />

<!-- ❌ Bad -->
<SolidColorBrush x:Key="AdornerLayerSolidBorderBrush" Color="Black" />
```

### Step 3: Per-Theme Customization / 按主题自定义

```xml
<ResourceDictionary x:Key="Light">
    <SolidColorBrush x:Key="MyControlBg" Color="{StaticResource SemiGrey0Color}" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
    <SolidColorBrush x:Key="MyControlBg" Color="{StaticResource SemiGrey9Color}" />
</ResourceDictionary>
```

### Naming Convention / 命名约定

| Scope / 范围 | Pattern / 模式 | Example / 示例 |
| --- | --- | --- |
| Base token / 基础令牌 | `Semi{Category}{Variant}` | `SemiColorText0`, `SemiSpacingBase` |
| Control-specific / 控件专属 | `{ControlName}{Role}` | `AdornerLayerSolidBorderBrush`, `ButtonDefaultBackground` |

See [Design Tokens](reference/design-tokens.md) for the complete base token reference.
参见 [设计令牌](reference/design-tokens.md) 获取完整基础令牌参考。

## Token Existence Guarantee / 令牌存在性保证

> **All tokens listed in this skill and in [Design Tokens](reference/design-tokens.md) are guaranteed to exist in the Semi.Avalonia assembly.** You do NOT need to de-compile the assembly or perform any other verification step to confirm their existence. Always reference them directly as `{DynamicResource <TokenKey>}` in your AXAML.
>
> **本 Skill 及[设计令牌](reference/design-tokens.md)中列出的所有令牌均保证存在于 Semi.Avalonia 程序集中。** 无需反编译程序集或进行任何额外验证。请直接在 AXAML 中使用 `{DynamicResource <TokenKey>}` 引用它们。

