Files
AtomUI/docs/Desktop.Controls/ToggleIconButton/ToggleIconButton.md
T

7.7 KiB
Raw Blame History

ToggleIconButton 切换图标按钮

概述

切换图标按钮(ToggleIconButton)是一个纯图标的切换按钮控件,在选中(Checked)和未选中(Unchecked)状态之间切换时可以显示不同的图标。它没有文本内容、无背景、无边框,仅通过图标和图标颜色来表达状态。

ToggleIconButton 常用于工具栏、面板头部的折叠/展开、收藏/取消收藏、排序方向切换等交互场景。在 Ant Design 中没有直接对应的组件,它是 AtomUI 基于 Avalonia ToggleButton 扩展的实用控件。


设计原理

设计定位

在 Ant Design 的组件体系中,切换类控件(Switch、Checkbox、Radio)都有较重的视觉表现和明确的表单语义。而在实际开发中,经常需要一种更轻量的切换方式——仅通过图标变化表达二元状态,不占据过多视觉空间。例如:

  • 折叠/展开:Collapse 面板的箭头图标在展开和收起时切换方向
  • 排序切换:表格列标题的排序图标在升序和降序之间切换
  • 收藏/取消:心形或星形图标在空心和实心之间切换

ToggleIconButton 就是为这类轻量切换场景设计的。

Avalonia ToggleButton 基础能力

AtomUI 的 ToggleIconButton 通过 AbstractToggleIconButton 继承自 Avalonia 的 Avalonia.Controls.Primitives.ToggleButton。理解 Avalonia ToggleButton 的基础能力有助于理解 ToggleIconButton 的交互基础。

Avalonia ToggleButton 的核心职责:

Avalonia 的 ToggleButton 继承自 Button,在标准按钮的点击行为之上增加了 IsChecked 状态管理。每次点击时 IsChecked 在 true / false(以及可选的 null)之间切换。它的继承链为:

Control → TemplatedControl → ContentControl → Button → ToggleButton

Avalonia ToggleButton 提供的基础属性:

属性 说明
IsChecked 切换状态:true(选中)、false(未选中)、null(不确定,当 IsThreeState=true 时)
IsThreeState 是否支持三态切换
Command / CommandParameter MVVM 命令绑定
ClickMode 点击触发时机
IsPressed 只读,是否处于按压状态

Avalonia ToggleButton 提供的基础伪类:

伪类 说明
:checked IsChecked == true
:unchecked IsChecked == false
:indeterminate IsChecked == null(三态模式)
:pointerover 鼠标悬浮
:pressed 按下
:disabled 禁用

AtomUI 的扩展设计

AtomUI ToggleIconButton 在 Avalonia ToggleButton 的基础上做了以下扩展:

扩展能力 实现方式 设计动机
双图标切换 CheckedIcon + UnCheckedIcon 属性 选中和未选中状态显示不同图标,通过模板中两个 IconPresenter 的可见性切换实现
精细颜色控制 NormalIconBrush / ActiveIconBrush / SelectedIconBrush / DisabledIconBrush 四种状态各有独立的颜色属性,主题根据伪类自动切换
当前生效颜色 IconBrush 属性 由主题根据当前状态自动设置的生效颜色
图标尺寸 IconWidth / IconHeight 属性 精确控制图标渲染尺寸
过渡动画 IMotionAwareControl + Background / RenderTransform 过渡 平滑的背景色和变换过渡
Design Token ButtonToken.ScopeProvider 复用 Button 的 Token 作用域

功能详解

双图标切换机制

ToggleIconButton 通过两个属性分别设置选中和未选中状态的图标:

属性 用途 可见性条件
CheckedIcon 选中状态(IsChecked = true)时显示的图标 :checked 伪类激活时可见
UnCheckedIcon 未选中状态(IsChecked = false)时显示的图标 :unchecked 伪类激活时可见

模板中包含两个 IconPresenter,通过 IsChecked 绑定控制它们的交替显示。

颜色状态系统

ToggleIconButton 提供了精细的颜色控制体系,支持四种状态各自独立的颜色定义:

属性 对应状态 说明
NormalIconBrush 未选中正常态 默认图标颜色
ActiveIconBrush 悬浮/按下态 鼠标悬浮或按下时的图标颜色
SelectedIconBrush 选中态 IsChecked = true 时的图标颜色
DisabledIconBrush 禁用态 IsEnabled = false 时的图标颜色
IconBrush 当前生效颜色 由主题根据当前状态自动赋值,实际渲染使用此属性

过渡动画

当 IsMotionEnabled = true 时,OnLoaded 阶段自动配置以下过渡:

  • Background:SolidColorBrushTransition(背景色平滑过渡)
  • RenderTransform:TransformOperationsTransition(缩放/旋转等变换平滑过渡)

OnUnloaded 时清除过渡,避免不可见控件消耗资源。


继承关系

Avalonia.Controls.Primitives.TemplatedControl
  └── Avalonia.Controls.ContentControl
        └── Avalonia.Controls.Button
              └── Avalonia.Controls.Primitives.ToggleButton
                    └── AtomUI.Controls.Commons.AbstractToggleIconButton (IMotionAwareControl)  ← 设备无关基类
                          └── AtomUI.Desktop.Controls.ToggleIconButton                          ← 桌面实现

各层级职责划分:

层级 提供的能力
Avalonia.Controls.Button 点击交互 → Click 事件、ICommand 绑定、IsPressed 状态
Avalonia.Controls.Primitives.ToggleButton IsChecked 状态管理、:checked / :unchecked 伪类、三态支持
AbstractToggleIconButton(基类层) CheckedIcon / UnCheckedIcon 双图标、四种颜色状态属性、IconWidth / IconHeight、过渡动画
ToggleIconButton(桌面层) 注册 ButtonToken.ScopeProvider,由主题控制视觉表现

实现的共享接口:

接口 定义位置 作用
IMotionAwareControl AtomUI.Controls 支持 IsMotionEnabled 过渡动画开关

源码位置

层级 文件路径 说明
基类 src/AtomUI.Controls/Buttons/AbstractToggleIconButton.cs 设备无关基类
控件类 src/AtomUI.Desktop.Controls/Buttons/ToggleIconButton.cs 桌面切换图标按钮
主题模板 src/AtomUI.Desktop.Controls/Buttons/Themes/ToggleIconButtonTheme.axaml ControlTheme AXAML
主题代码 src/AtomUI.Desktop.Controls/Buttons/Themes/ToggleIconButtonTheme.cs 主题 Code-behind
主题常量 src/AtomUI.Desktop.Controls/Buttons/Themes/ToggleIconButtonThemeConstants.cs 模板部件名常量

模板结构

Border#Frame (背景 + 边框 + 圆角)
  └── Panel#RootLayout (叠层容器)
        ├── IconPresenter#CheckedIconPresenter   (选中图标,IsChecked=True 时可见)
        └── IconPresenter#UnCheckedIconPresenter (未选中图标,IsChecked=False 时可见)

模板设计理由:

  • Panel 叠层容器:两个 IconPresenter 叠加放置在同一位置,通过 IsVisible 绑定 IsChecked 实现交替显示。使用 Panel 而非 Grid 是因为只需简单叠层,无需行列定义。
  • 两个独立 IconPresenter:分开两个图标展示器而非运行时替换 Icon 属性,避免了图标切换时的测量/排列抖动。

模板部件常量

常量名 值 说明
ToggleIconButtonThemeConstants.RootLayoutPart "PART_RootLayout" 根布局面板
ToggleIconButtonThemeConstants.CheckedIconPresenterPart "PART_CheckedIconPresenter" 选中态图标展示器
ToggleIconButtonThemeConstants.UnCheckedIconPresenterPart "PART_UnCheckedIconPresenter" 未选中态图标展示器