mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-20 15:52:17 +08:00
7.8 KiB
7.8 KiB
Card 自定义样式指南
Card 的视觉表现通过 ControlTheme + Design Token 系统控制。以下介绍几种常见的自定义方式。
1. 使用属性直接控制
最简单的方式是通过 Card 的公共属性来控制外观:
<!-- 不同风格 -->
<atom:Card Header="Card Title">
<atom:TextBlock>Default card with border</atom:TextBlock>
</atom:Card>
<atom:Card Header="Card Title" StyleVariant="Borderless">
<atom:TextBlock>Borderless card with shadow</atom:TextBlock>
</atom:Card>
<!-- 不同尺寸 -->
<atom:Card Header="Large Card" SizeType="Large" Width="300">
<atom:TextBlock>Large card content</atom:TextBlock>
</atom:Card>
<atom:Card Header="Default Card" SizeType="Middle" Width="300">
<atom:TextBlock>Default card content</atom:TextBlock>
</atom:Card>
<atom:Card Header="Small Card" SizeType="Small" Width="300">
<atom:TextBlock>Small card content</atom:TextBlock>
</atom:Card>
<!-- 悬浮阴影 -->
<atom:Card Header="Hoverable" IsHoverable="True" Width="300">
<atom:TextBlock>Hover me to see shadow effect!</atom:TextBlock>
</atom:Card>
<!-- 内嵌模式 -->
<atom:Card Header="Outer Card" SizeType="Large">
<StackPanel Spacing="20">
<atom:Card Header="Inner Card 1" IsInnerMode="True">
<atom:TextBlock>Inner card content</atom:TextBlock>
</atom:Card>
<atom:Card Header="Inner Card 2" IsInnerMode="True">
<atom:TextBlock>Inner card content</atom:TextBlock>
</atom:Card>
</StackPanel>
</atom:Card>
<!-- 带封面和操作区 -->
<atom:Card Width="300" IsHoverable="True">
<atom:Card.Cover>
<Image Source="/Assets/CardShowCase/Cover1.png" />
</atom:Card.Cover>
<atom:CardMetaContent Header="Europe Street beat"
Content="www.instagram.com" />
<atom:Card.Actions>
<atom:CardActionButton Icon="{antdicons:AntDesignIconProvider Kind=EditOutlined}" />
<atom:CardActionButton Icon="{antdicons:AntDesignIconProvider Kind=SettingOutlined}" />
</atom:Card.Actions>
</atom:Card>
<!-- 加载状态 -->
<atom:Card Header="Loading Card" IsLoading="True" Width="300">
<atom:TextBlock>This content is hidden during loading</atom:TextBlock>
</atom:Card>
📖 完整示例参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/CardShowCase.axaml
2. 通过 Style 覆盖样式
可以在 AXAML 中使用 Style 对 Card 进行全局或局部样式覆盖:
全局统一间距
<Window.Styles>
<Style Selector="atom|Card">
<Setter Property="Margin" Value="10" />
</Style>
</Window.Styles>
按风格定制
<!-- 所有无边框卡片添加自定义阴影 -->
<Style Selector="atom|Card[StyleVariant=Borderless]">
<Setter Property="BoxShadow" Value="0 2 8 0 #33000000" />
</Style>
使用伪类选择器
<!-- 无标题卡片的自定义边框 -->
<Style Selector="atom|Card:headerless">
<Setter Property="BorderBrush" Value="LightGray" />
</Style>
<!-- 禁用态的自定义透明度 -->
<Style Selector="atom|Card:disabled">
<Setter Property="Opacity" Value="0.5" />
</Style>
按属性选择器定制
<!-- 所有小号卡片使用紧凑内边距 -->
<Style Selector="atom|Card[SizeType=Small]">
<Setter Property="Margin" Value="4" />
</Style>
<!-- 所有悬浮卡片添加手形光标 -->
<Style Selector="atom|Card[IsHoverable=True]">
<Setter Property="Cursor" Value="Hand" />
</Style>
<!-- 内嵌模式卡片的额外样式 -->
<Style Selector="atom|Card[IsInnerMode=True]">
<Setter Property="Margin" Value="0 0 0 16" />
</Style>
访问模板内部部件
<!-- 自定义头部区域边框颜色 -->
<Style Selector="atom|Card /template/ Border#HeaderFrame">
<Setter Property="BorderBrush" Value="#e8e8e8" />
</Style>
<!-- 自定义内容区域内边距 -->
<Style Selector="atom|Card /template/ Border#CardContent">
<Setter Property="Padding" Value="24" />
</Style>
3. 通过 ControlTheme 完全替换主题
如果需要彻底替换 Card 的模板和样式,可以定义自定义 ControlTheme:
<ControlTheme x:Key="MyCustomCard" TargetType="atom:Card">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<DockPanel LastChildFill="True">
<ContentPresenter DockPanel.Dock="Top"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}" />
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</DockPanel>
</Border>
</ControlTemplate>
</Setter>
</ControlTheme>
<!-- 使用 -->
<atom:Card Theme="{StaticResource MyCustomCard}" Header="Custom Card">
<atom:TextBlock>Custom card content</atom:TextBlock>
</atom:Card>
⚠️ 注意:完全替换 ControlTheme 将丢失内置的骨架屏加载、操作区面板、封面圆角裁剪等功能。建议优先使用 Style 覆盖。
4. 控制动画行为
<!-- 禁用过渡动画(BoxShadow 不再渐变过渡) -->
<atom:Card Header="No Animation" IsMotionEnabled="False" IsHoverable="True">
<atom:TextBlock>Shadow changes instantly</atom:TextBlock>
</atom:Card>
样式选择器速查
说明:Avalonia 样式选择器中使用
atom|Card语法引用atomXML 命名空间下的Card类型,其中|是命名空间分隔符。
按风格选择
| 选择器 | 说明 |
|---|---|
atom|Card |
匹配所有 AtomUI Card 实例 |
atom|Card[StyleVariant=Outline] |
匹配有边框的卡片(默认风格) |
atom|Card[StyleVariant=Borderless] |
匹配无边框的卡片(使用阴影替代边框) |
按尺寸选择
| 选择器 | 说明 |
|---|---|
atom|Card[SizeType=Large] |
匹配大号卡片 |
atom|Card[SizeType=Middle] |
匹配中号卡片(默认) |
atom|Card[SizeType=Small] |
匹配小号卡片 |
按状态属性选择
| 选择器 | 说明 |
|---|---|
atom|Card[IsHoverable=True] |
匹配启用悬浮阴影的卡片 |
atom|Card[IsInnerMode=True] |
匹配内嵌模式的卡片 |
atom|Card[IsLoading=True] |
匹配加载中状态的卡片 |
按伪类选择
| 选择器 | 说明 |
|---|---|
atom|Card:headerless |
匹配无标题区域的卡片(Header / Extra 均为 null) |
atom|Card:pointerover |
匹配鼠标悬浮的卡片 |
atom|Card:disabled |
匹配禁用状态的卡片 |
组合选择器示例
| 选择器 | 说明 |
|---|---|
atom|Card[IsHoverable=True]:pointerover |
悬浮态的可交互卡片(阴影加深状态) |
atom|Card[SizeType=Large]:headerless |
大号无标题卡片 |
atom|Card[StyleVariant=Borderless][IsInnerMode=True] |
无边框的内嵌卡片 |
atom|Card /template/ Border#Frame |
访问卡片模板内的主框架 Border |
atom|Card /template/ Border#HeaderFrame |
访问卡片模板内的头部区域 |
atom|Card /template/ Border#CardContent |
访问卡片模板内的内容区域 |
相关控件选择器
| 选择器 | 说明 |
|---|---|
atom|CardMetaContent |
匹配所有 CardMetaContent 实例 |
atom|CardGridItem |
匹配所有网格单元格 |
atom|CardGridItem[IsHoverable=True]:pointerover |
匹配悬浮态的网格单元格 |
atom|CardActionButton |
匹配所有操作区按钮 |
atom|CardActionButton:pointerover |
匹配悬浮态的操作区按钮(图标变主色) |