首先看一段样例代码:
<StackPanel Orientation="Horizontal" Spacing="50" HorizontalAlignment="Center">
<StackPanel.Styles>
<Style Selector="Button.default">
<Setter Property="Background" Value="Red"/>
</Style>
</StackPanel.Styles>
<!--Left Button-->
<Button Classes="default" Width="100" Height="100" Background="Blue"/>
<!--Right Button-->
<ContentControl>
<ContentControl.Template>
<ControlTemplate>
<Button Classes="default" Width="100" Height="100" Background="Blue"/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</StackPanel>
这段代码中有两个Button,且它们的属性值一模一样,只不过一个在LogicalTree中,一个在ControlTemplate中。仅仅这个区别,使得它们的呈现效果完全不一样,如下图:
左侧Button的Background生效了,而右侧Button的Background值没有生效,为什么会这样?
这里就不得不说Avalonia的Setter优先级机制了,官方给出的优先级清单如下:
Animation = -1, // Highest priority
LocalValue = 0,
StyleTrigger,
Template,
Style,
Inherited,
Unset = int.MaxValue, // Lowest priority
从上面可以看到,StyleTrigger的优先级是高于Template的,所以尽管在Template中设置了Background,但它的优先级和Template是等同的,因此优先级仍然没有Style中的Background高。
这一点我也在Github上得到了明确的解答,原回答如下:
简而言之就是,在Template中是没有办法覆盖Style中设置的属性的!!
以上案例也凸显了Avalonia和WPF的属性值优先级的不同。
在WPF中,Template的属性值优先级是高于Style的,官方文档如下:
依赖项属性值优先级 - WPF .NET | Microsoft Learn
可以编写对比代码进行验证这一点:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel.Resources>
<Style x:Key="DefaultButton" TargetType="Button">
<Setter Property="Background" Value="Red"/>
</Style>
</StackPanel.Resources>
<!--Left Button-->
<Button Style="{StaticResource DefaultButton}" Width="100" Height="100" Background="Blue"/>
<!--Right Button-->
<ContentControl Margin="50,0,0,0">
<ContentControl.Template>
<ControlTemplate>
<Button Style="{StaticResource DefaultButton}" Width="100" Height="100" Background="Blue"/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</StackPanel>
效果如下:
两个按钮都被设置成了蓝色!
觉得有用就点个赞和关注吧,和我一起在Avalonia中爬坑>_<