资源,是可以在应用中的不同位置重复使用的对象。
资源的示例包括画笔和样式。
本文介绍了如何使用XAML中的资源。当然,我们还可以通过代码创建和访问资源。XAML资源与‘应用资源’不同,后者通常指添加到应用中的文件,例如内容、数据或嵌入式文件。
使用XAML中的资源
下面的示例将SolidColorBrush定义为页面根元素上的资源。该示例随后引用资源,并使用它来设置多个子元素的属性,包括Ellipse、TextBlock和Button:
<Page Name="root" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Page.Resources> <SolidColorBrush x:Key="MyBrush" Color="Gold"/> <Style TargetType="Border" x:Key="PageBackground"> <Setter Property="Background" Value="Blue"/> </Style> <Style TargetType="TextBlock" x:Key="TitleText"> <Setter Property="Background" Value="Blue"/> <Setter Property="DockPanel.Dock" Value="Top"/> <Setter Property="FontSize" Value="18"/> <Setter Property="Foreground" Value="#4E87D4"/> <Setter Property="FontFamily" Value="Trebuchet MS"/> <Setter Property="Margin" Value="0,40,10,10"/> </Style> <Style TargetType="TextBlock" x:Key="Label"> <Setter Property="DockPanel.Dock" Value="Right"/> <Setter Property="FontSize" Value="8"/> <Setter Property="Foreground" Value="{StaticResource MyBrush}"/> <Setter Property="FontFamily" Value="Arial"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Margin" Value="0,3,10,0"/> </Style> </Page.Resources> <StackPanel> <Border Style="{StaticResource PageBackground}"> <DockPanel> <TextBlock Style="{StaticResource TitleText}">Title</TextBlock> <TextBlock Style="{StaticResource Label}">Label</TextBlock> <TextBlock DockPanel.Dock="Top" HorizontalAlignment="Left" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" /> <Button DockPanel.Dock="Top" HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button> <Ellipse DockPanel.Dock="Top" HorizontalAlignment="Left" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="40" /> </DockPanel> </Border> </StackPanel> </Page>
Page。
资源的非字符串键用于 WPF 中的某些功能区,尤其是样式、组件资源和数据样式。
例如,将资源用作另一个元素上的属性的值。
<Button Background="{StaticResource MyBrush}"/> <Ellipse Fill="{StaticResource MyBrush}"/>
Fill。
静态和动态资源
DynamicResource 标记扩展则通过创建表达式来处理键,而且表达式会保持未计算状态,直至应用运行为止。当应用实际运行时,表达式会进行计算并提供一个值。
在引用某个资源时,下列注意事项可能会对于使用静态资源引用还是使用动态资源引用产生影响:
-
确定如何为应用创建资源的整体设计(在每页上、在应用程序中、在宽松的 XAML 中或在仅包含资源的程序集中)时,请考虑以下事项:
-
实时更新资源是否为应用要求的一部分?
-
该资源引用类型的相应查找行为。
-
特定的属性或资源类型,以及这些类型的本机行为。
静态资源
在以下情况下,最适合使用静态资源引用:
-
因此,根据资源和应用设计,如果避免不必要地使用大量动态资源引用,可能会一定程度地提高性能。
-
Freezable 上的属性的值。
-
要创建的资源字典将编译成 DLL,并将打包为应用的一部分或在应用间共享。
-
如果发生这种情况,主题的行为将偏离预期方式。
-
此项技术可以提高性能。
-
x:Shared 属性为每个使用者维护单独的可写实例。
静态资源查找行为:
下面介绍属性或元素引用静态资源时自动发生的查找过程:
-
查找进程在用于设置属性的元素所定义的资源字典中查找请求的键。
-
此过程到达根元素后才会停止。
-
Application 对象为 WPF 应用定义的资源字典中的资源。
因此,请设计资源字典的结构,以便在每个相应资源字典的开头或邻近开头的位置定义资源。
出于上述原因,这些引用应该是静态资源引用。
如果资源未延迟,则异常会在加载时发生。
动态资源
在以下情况下,最适合使用动态资源:
-
或许还拥有可能会发生变化的应用程序级主题,而页面级资源访问也必须捕获其中的变化。
-
要为自定义控件创建或引用主题样式。
-
ResourceDictionary 的内容。
-
静态资源引用不支持前向引用,但动态资源引用支持,因为资源在运行时之前不需要计算,所以前向引用是一个不相关的概念。
-
但是,动态资源引用在使用前不会加载。
-
要创建的样式的 setter 值可能来自受主题或其他用户设置影响的其他值。
-
父级更改后,资源查找范围也可能会随之更改;因此,如果希望重定父级的元素的资源基于新范围重新进行计算,请始终使用动态资源引用。
动态资源查找行为
SetResourceReference,则动态资源引用的资源查找行为会与代码中的查找行为并行执行:
-
查找在用于设置属性的元素所定义的资源字典中查找请求的键:
-
Resources 字典。
-
System.Windows.FrameworkTemplate.Resources 字典。
-
-
此过程到达根元素后才会停止。
-
Application 对象为 WPF 应用定义的资源字典中的资源。
-
如果主题在运行时发生更改,则会重新计算值。
-
检查系统资源。
异常行为(如果有)各不相同:
-
FindResource 调用请求了某个资源但未找到该资源,则会引发异常。
-
如果要设置的属性不接受
null,则仍有可能引发更深的异常(取决于要设置的单独属性)。 -
对于并非由主题样式定义的属性,资源计算失败后的有效值可能来自属性元数据中的默认值。
动态资源的限制
必须至少满足以下条件之一:
-
DependencyProperty 支持。
-
该引用用于
StyleSetter内的值。 -
Setter 值的形式提供)上的属性。
此功能可能仍会因属性、属性所属的类型,甚至应用的逻辑结构而异。
样式、DataTemplate和隐式键
任何隐式键都可通过指定显式键来覆盖。
样式设置和模板化。
Style 资源似乎没有键,以下样式定义仍起作用:
<Style TargetType="Button"> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush> <GradientStop Offset="0.0" Color="AliceBlue"/> <GradientStop Offset="1.0" Color="Salmon"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="FontSize" Value="18"/> </Style>
Type)。
TargetType 的类型值相同的键,以求在标记中清楚明示,但这是可选的。
可样式化控件的设计指南。
数据模板化概述。