当前位置: 首页 > ops >正文

从 WPF 到 Avalonia 的迁移系列实战篇6:ControlTheme 和 Style区别

从 WPF 到 Avalonia 的迁移系列实战篇6:ControlTheme 和 Style区别

我的GitHub仓库Avalonia学习项目包含完整的Avalonia实践案例与代码对比。
我的gitcode仓库是Avalonia学习项目。

前言

在之前的文章中,我们介绍了 Avalonia 的基础样式系统。本文将结合实际示例,展示 Avalonia 11 新引入的 ControlTheme 与传统 Style 的区别,帮助大家更直观地理解两者的适用场景。


ControlTheme 与 Style 的差异回顾

  • ControlTheme

    • 定义控件外观主题。
    • 通过 Theme 属性应用到控件。
    • 支持 BasedOn 继承,可重用。
    • 一次只能应用一个主题(互斥)。
  • Style

    • 通过选择器和 Classes 应用。
    • 不支持 BasedOn,容易重复代码。
    • 可以叠加多个样式(更灵活)。

实战对比示例

我们通过定义 两种按钮样式(白字按钮 和 黑字按钮) 来对比 ControlTheme 与 Style 的使用效果。

使用 ControlTheme

<ControlTheme TargetType="{x:Type Button}" x:Key="WhiteForegroundButtonStyle"><Setter Property="Background" Value="LightBlue" /><Setter Property="Foreground" Value="White" /><Setter Property="FontWeight" Value="Bold" /><Setter Property="BorderThickness" Value="0" /><Setter Property="Padding" Value="12,6" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><Border Background="{TemplateBinding Background}" CornerRadius="0"><ContentPresenterContent="{TemplateBinding Content}"HorizontalAlignment="Center"VerticalAlignment="Center" /></Border></ControlTemplate></Setter.Value></Setter><Style Selector="^:pointerover"><Setter Property="Foreground" Value="DodgerBlue" /></Style>
</ControlTheme><ControlThemeBasedOn="{StaticResource WhiteForegroundButtonStyle}"TargetType="{x:Type Button}"x:Key="BlackForegroundButtonStyle"><Setter Property="Foreground" Value="Black" />
</ControlTheme>
使用方式
<Button Theme="{StaticResource WhiteForegroundButtonStyle}">白字按钮</Button>
<Button Theme="{StaticResource BlackForegroundButtonStyle}">黑字按钮</Button>

👉 优点:

  • 只需定义一次基础主题,通过 BasedOn 即可派生新主题。
  • 适合 可切换的控件外观,比如深色/浅色主题按钮。

使用 Style

<Style Selector="Button.squareWhiteForeground"><Setter Property="Background" Value="LightBlue" /><Setter Property="Foreground" Value="White" /><Setter Property="FontWeight" Value="Bold" /><Setter Property="BorderThickness" Value="0" /><Setter Property="Padding" Value="12,6" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><Border Background="{TemplateBinding Background}" CornerRadius="0"><ContentPresenterContent="{TemplateBinding Content}"HorizontalAlignment="Center"VerticalAlignment="Center" /></Border></ControlTemplate></Setter.Value></Setter>
</Style>
<Style Selector="Button.squareWhiteForeground:pointerover"><Setter Property="Foreground" Value="DodgerBlue" />
</Style><Style Selector="Button.squareBlackForeground"><Setter Property="Background" Value="LightBlue" /><Setter Property="Foreground" Value="Black" /><Setter Property="FontWeight" Value="Bold" /><Setter Property="BorderThickness" Value="0" /><Setter Property="Padding" Value="12,6" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><Border Background="{TemplateBinding Background}" CornerRadius="0"><ContentPresenterContent="{TemplateBinding Content}"HorizontalAlignment="Center"VerticalAlignment="Center" /></Border></ControlTemplate></Setter.Value></Setter>
</Style>
<Style Selector="Button.squareBlackForeground:pointerover"><Setter Property="Foreground" Value="DodgerBlue" />
</Style>
使用方式
<Button Classes="squareWhiteForeground">白字按钮</Button>
<Button Classes="squareBlackForeground">黑字按钮</Button>

👉 缺点:

  • 黑白两套样式几乎完全重复,无法 BasedOn 继承。
  • 如果需要维护多个按钮风格,样式代码会迅速膨胀。

对比总结

特性StyleControlTheme
目标通过 Selector(选择器)匹配控件通过 TargetType 明确目标控件类型
应用方式控件通过 Class 或 Selector 应用控件通过 Theme 属性应用(替换而不是叠加)
存储位置通常放在 <Styles>通常放在 ResourceDictionary
继承支持不支持 BasedOn支持 BasedOn
多主题支持需手动切换样式集合支持 ThemeVariant,可全局或局部切换 Light/Dark 等

控件主题的查找规则

Avalonia 查找 ControlTheme 的方式有两种:

  1. 如果控件的 Theme 属性被设置,则优先使用该主题;
  2. 否则,Avalonia 会沿逻辑树向上搜索 ControlTheme,查找一个 x:Key 与控件样式键匹配的资源。

两种定义方式

  • 如果希望主题应用于所有实例:

    <ControlTheme x:Key="{x:Type Button}" TargetType="Button">...
    </ControlTheme>
    
  • 如果只想应用于特定实例:

    <ControlTheme x:Key="EllipseButton" TargetType="Button">...
    </ControlTheme>
    

    然后在控件上显式设置 Theme="{StaticResource EllipseButton}"


迁移建议(WPF → Avalonia)

在 WPF 中:

  • 控件外观通过 Style + ControlTemplate 定义;
  • 没有 ThemeDictionary 概念,Light/Dark 主题需要手动维护多份 ResourceDictionary
  • 样式支持 BasedOn,可以复用。

在 Avalonia 中:

  • 默认主题可以通过 ControlTheme 定义在资源字典中;
  • 支持 ThemeVariant,原生支持 Light/Dark 切换;
  • ControlTheme 支持 BasedOn,比普通样式更适合做主题继承;
  • 普通 Style 没有 BasedOn,更多依赖 Classes + Selector。
  • 如果是 控件主题(可切换外观) → 使用 ControlTheme
  • 如果是 局部样式修饰/条件状态 → 使用 Style

总结

本篇我们通过 白字按钮 vs 黑字按钮 的 Demo,直观对比了 ControlTheme 与 Style 的核心区别

  • Style 更适合定义局部样式,通过 Selector 和 Class 应用。
  • ControlTheme 更适合定义可替换的控件外观(尤其是模板控件),支持 ThemeVariantBasedOn,便于多主题切换。
  • WPF 迁移到 Avalonia 时,可以将 generic.xaml 中的默认样式迁移为 ControlTheme,并利用 ThemeVariant 来实现 Light/Dark 主题支持。

这样既能保留 WPF 开发的经验,又能充分利用 Avalonia 11 带来的新特性。

我的GitHub仓库Avalonia学习项目包含完整的Avalonia实践案例与代码对比。
我的gitcode仓库是Avalonia学习项目。

http://www.xdnf.cn/news/19536.html

相关文章:

  • .NetCore下Ocelot + Nacos 实现负载均衡
  • qt QWebSocket详解
  • 数据结构与算法个人学习代码笔记包含leetcode,海贼oj,蓝桥杯,ACM
  • 对于牛客网—语言学习篇—编程初学者入门训练—复合类型:BC140 杨辉三角、BC133 回型矩阵、BC134 蛇形矩阵题目的解析
  • Ansible 变量与加密文件全解析:从基础定义到安全实践
  • 了解名词ARM Linux的SOC
  • TIOBE 8月编程语言榜深度解析:Python占比突破26%,Perl成最大黑马
  • Kaia AMA 全回顾:如何让 Web3 无痕融入2.5 亿用户日常?9 月 7 日中国行揭秘!
  • 一键提取,是真强呀!~
  • buuctf_php(极客大挑战 2019)
  • 从程序员到「认识罕见病 DAO」发起人,他用 Web3 承载爱与责任
  • Linux 文本处理四剑客:cut, sort, uniq, tr
  • lua脚本在redis中如何单步调试?
  • 一文吃透 deviceQuery:从安装到输出解读,彻底验证服务器 GPU 环境
  • AlDente Pro for Mac电脑 充电限制保护工具
  • Go 面试题:Goroutine 和 GMP 模型解析
  • 最快的 C 语言 JSON 库 - yyjson
  • 阿里云日志服务之WebTracking 小程序端 JavaScript SDK (阿里SDK埋点和原生uni.request请求冲突问题)
  • 2025全球绿色发展与健康生活方式高峰论坛 推动HLCC国际认证体系全球化实施
  • VGG改进(7):基于Spatial Attention的性能优化
  • 跨平台游戏引擎 Axmol-2.8.0 发布
  • Prettier代码格式化工具测评:支持JS/TS/Vue多语言,兼容ESLint实现团队代码格式统一
  • TKDE-2022《Low-Rank Linear Embedding for Robust Clustering》
  • Element-Plus 入门指南
  • 【3D通用视觉框架】基于Qt5开发的3D视觉框架软件,纯底层,全套源码,开箱即用
  • R语言根据经纬度获得对应样本的省份
  • PCB设计规范
  • redis-----java客户端
  • K8s集群+Rancher Server:部署DolphinScheduler 3.2.2集群
  • 【vue2】vue2.7x的项目中集成tailwind.css真的不要太香