跳到主要内容

自定义资源 - 进阶

覆写色彩相关的动态资源

色彩相关的资源(如Brush)的覆写本应与其他资源一致,但考虑到色彩与亮暗主题相关,因此在覆写的时候可能需要对不同的主题分别覆写。

示例:

我希望将 Button 的文字颜色改为紫色,但为了保证在亮色和暗色模式下都有比较好的辨识度,设计师认为在亮色时应为 #9E28B3,在暗色时应为 #B553C2

通过 Semi Avalonia 的源代码 /src/Semi.Avalonia/Controls/Button.axaml 我们可以看到,Button 的 Foreground 通过如下方式赋值:

/src/Semi.Avalonia/Controls/Button.axaml
 <ControlTheme x:Key="{x:Type Button}" TargetType="Button">
<!--省略无关代码-->
<Setter Property="Foreground" Value="{DynamicResource ButtonDefaultPrimaryForeground}" />
<!--省略无关代码-->
</ControlTheme>

通过源代码我们可以看到 ButtonDefaultPrimaryForeground 在亮色和暗色中分别被定义为:

/src/Semi.Avalonia/Themes/Light/Button.axaml
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#0077FA" />
/src/Semi.Avalonia/Themes/Dark/Button.axaml
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#54A9FF" />

因此我们可以在App.axaml中重新为这个资源赋值。

App.axaml
<Application
x:Class="Semi.Avalonia.Demo.App"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:semi="https://irihi.tech/semi"
RequestedThemeVariant="Light"
>
<Application.Styles>
<semi:SemiTheme Locale="zh-CN"/>
</Application.Styles>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#9E28B3"/>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#B553C2"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

如此,应用中的按钮前景色都会变为紫色,并且在亮色和暗色中有不同的色值。

局部覆写资源

在 Avalonia 中,控件获取资源的方式是沿视觉树不断向上,在各级的资源字典中寻找,直到找到为止。因此如果您只想在局部改变资源,可以在其附近的资源字典中局部覆写

例如我在一个 Window 中有若干 Button ,但我只希望其内部一个 StackPanel 中的 Button 的文字颜色变为紫色,那么您可以通过下面的方式覆写资源:

<Window
x:Class="Semi.Avalonia.Demo.Views.MainWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<WrapPanel>
<Button Content="Button 1.1"/>
<Button Content="Button 1.2"/>
</WrapPanel>
<StackPanel>
<StackPanel.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#9E28B3"/>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ButtonDefaultPrimaryForeground" Color="#B553C2"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</StackPanel.Resources>
<Button Content="Button 2.1"/>
<Button Content="Button 2.2"/>
</StackPanel>
</Grid>
</Window>

如此,WrapPanel中的按钮仍为蓝色,但StackPanel中的按钮会变为紫色。