通常,样式和控件需要共享资源,比如(但不限于)笔刷(brush)和颜色(color)。你可以把这些资源放在每个样式和控件共有的 Resources
字典里,然后在其他地方引用这些资源。
定义资源
如果一个资源要作用在整个应用程序上,你可以在App.xaml
/App.axaml
中定义它。
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.App">
<Application.Resources>
<SolidColorBrush x:Key="Warning">Yellow</SolidColorBrush>
</Application.Resources>
</Application>
另外,你可以在Window
或UserControl
上声明资源:该资源将可用于Window
/UserControl
及其子代。
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.MyUserControl">
<UserControl.Resources>
<SolidColorBrush x:Key="Warning">Yellow</SolidColorBrush>
</UserControl.Resources>
</UserControl>
或者实际上对任何控件都可用:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.MainWindow">
<StackPanel>
<StackPanel.Resources>
<SolidColorBrush x:Key="Warning">Yellow</SolidColorBrush>
</StackPanel.Resources>
</StackPanel>
</Window>
你也可以在样式上声明资源。
<Style Selector="TextBlock.warn">
<Style.Resources>
<SolidColorBrush x:Key="Warning">Yellow</SolidColorBrush>
</Style.Resources>
</Style>
引用资源
你可以使用{DynamicResource}
标记扩展从控件中引用资源,例如:
<Border Background="{DynamicResource Warning}">
Look out!
</Border>
另外,还有StaticResource
标记扩展,与DynamicResource
相比,它有一些限制:
作为交换,StaticResource
不需要添加事件处理程序来监听资源的变化,这意味着它使用的内存较少。
覆盖资源
通过从DynamicResource
或StaticResource
节点向上遍历逻辑树,直到找到满足要求的键(key)的资源。这意味着资源可以在应用程序的子树中被覆盖,例如:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.MyUserControl">
<UserControl.Resources>
<SolidColorBrush x:Key="Warning">Yellow</SolidColorBrush>
</UserControl.Resources>
<StackPanel>
<StackPanel.Resources>
<SolidColorBrush x:Key="Warning">Orange</SolidColorBrush>
</StackPanel.Resources>
<Border Background="{DynamicResource Warning}">
Look out!
</Border>
</StackPanel>
</UserControl>
这里Border
的背景色是Orange
,因为它的父级StackPanel
已经覆盖了从UserControl
上声明的Yellow
中的Warning
资源。
合并的资源字典
每个控件和样式的Resources
属性的类型为ResourceDictionary
。通过使用MergedDictionaries
属性,资源字典还可以包括其他资源字典。要在另一个资源字典中包括资源字典,可以使用ResourceInclude
类,例如:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source='/AnotherResourceDictionary.xaml'/>
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="Warning">Yellow</SolidColorBrush>
</ResourceDictionary>
</Window.Resources>
其中,AnotherResourceDictionary
是根为ResourceDictionary
的XAML文件,并作为资产(asset)包含在应用程序中。
资源解析
如上所述,通过从DynamicResource
或StaticResource
节点向上遍历逻辑树来解析资源,直到找到满足条件的键(key)的资源。然而,样式和合并字典的存在使这一点有些复杂。优先级如下:
控件资源(Control resources)
合并字典(Merged dictionaries)
样式资源(Style resources)
合并字典(Merged dictionaries)
如下所示的应用程序,Border
控件上定义的资源的查找顺序将遵循[]
括号中指示的顺序:
Application
|- Resources [11]
|- Merged dictionary [12]
|- Merged dictionary [13]
|- Styles
|- Resources [14]
|- Merged dictionary [15]
|- Merged dictionary [16]
Window
|- Resources [6]
|- Merged dictionary [7]
|- Styles
|- Resources [8]
|- Merged dictionary [9]
|- Merged dictionary [10]
|- StackPanel
|- Resources [1]
|- Merged dictionary [2]
|- Merged dictionary [3]
|- Styles
|- Resources [4]
|- Merged dictionary [5]
|- Border
主题资源
主题通常将笔刷、颜色和其他设置定义为资源。通过改变这些资源,例如可以从暗黑主题切换到明亮主题。定义的资源通常特定于使用中的主题,但您可以在这里看到默认主题定义的资源。