如何定义和引用 WPF 资源(WPF .NET)
此示例演示如何定义资源并引用它。 资源可以通过 XAML 或代码进行引用。
XAML 示例
以下示例定义了两种类型的资源:SolidColorBrush 资源,以及多个 Style 资源。
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="#05E0E9"/>
<Style TargetType="Border">
<Setter Property="Background" Value="#4E1A3D" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="#4E1A3D"/>
<GradientStop Offset="1.0" Color="Salmon"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBlock" x:Key="TitleText">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="#4E87D4"/>
<Setter Property="FontFamily" Value="Trebuchet MS"/>
<Setter Property="Margin" Value="0,10,10,10"/>
</Style>
<Style TargetType="TextBlock" x:Key="Label">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="FontSize" Value="13"/>
<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>
</Window.Resources>
资源
SolidColorBrush 资源 MyBrush
用于提供多个属性的值,每个属性都采用 Brush 类型的值。 此资源通过 x:Key
值引用。
<Border>
<StackPanel>
<TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
<TextBlock Style="{StaticResource Label}">Label</TextBlock>
<TextBlock HorizontalAlignment="Right" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
<Button HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
<Ellipse HorizontalAlignment="Center" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="10" />
</StackPanel>
</Border>
在前面的示例中,MyBrush
资源使用 StaticResource 标记扩展进行访问。 资源分配给可接受所定义资源的类型的属性。 在此示例中为 Background、Foreground 和 Fill 属性。
资源字典中的所有资源都必须提供键。 但是,在定义样式时,它们可以省略键,如下一部分中所述。
如果使用 StaticResource 标记扩展从其他资源中引用资源,则也会按照在字典中找到的顺序请求资源。 请确保在集合中定义的任何资源都早于请求该资源的位置。 有关详细信息,请参阅 静态资源。
如有必要,可通过使用 DynamicResource 标记扩展在运行时引用资源来解决资源引用的严格创建顺序,但你需要知道,这种 DynamicResource
技术会影响性能。 有关详细信息,请参阅 动态资源。
样式资源
下面的例子隐式与显式地引用了样式:
<Border>
<StackPanel>
<TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
<TextBlock Style="{StaticResource Label}">Label</TextBlock>
<TextBlock HorizontalAlignment="Right" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
<Button HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
<Ellipse HorizontalAlignment="Center" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="10" />
</StackPanel>
</Border>
在前面的代码示例中,Style 资源 TitleText
和 Label
,每个资源都面向特定的控件类型。 在本例中,它们都以 TextBlock 为目标。 当该样式资源由其 Style 属性的资源键引用时,这些样式将在目标控件上设置各种不同的属性。
样式虽然以 Border 控件为目标,但并不定义键。 当某个键被省略时,TargetType 属性所针对的对象类型将被隐式作为样式的键使用。 当一个样式被锁定到某种类型时,只要这些控件在该样式的范围内,它就会成为这一类型所有控件的默认样式。 有关详细信息,请参阅 样式、DataTemplates 和隐式键。
代码示例
以下代码片段演示如何通过代码创建和设置资源
创建样式资源
创建资源并将其分配给资源字典可以随时发生。 但是,创建动态资源后,只有使用 DynamicResource 语法的 XAML 元素才会自动更新该资源。
以以下窗口为例。 它有四个按钮。 第四个按钮使用 DynamicResource 来设置自己的样式。 但是,此资源尚不存在,因此它看起来像正常按钮:
<StackPanel Margin="5">
<Button Click="Button_Click">Explicitly Styled</Button>
<Button>Unstyled</Button>
<Button>Unstyled</Button>
<Button Style="{DynamicResource ResourceKey=buttonStyle1}">Dynamically Styled</Button>
</StackPanel>
之前
单击第一个按钮并执行以下任务时,将调用以下代码:
- 创建一些颜色以方便参考。
- 创建新样式。
- 为样式分配资源库。
- 将样式作为名为
buttonStyle1
的资源添加到窗口的资源字典中。 - 将样式直接分配给引发
Click
事件的按钮。
private void Button_Click(object sender, RoutedEventArgs e)
{
// Create colors
Color purple = (Color)ColorConverter.ConvertFromString("#4E1A3D");
Color white = Colors.White;
Color salmon = Colors.Salmon;
// Create a new style for a button
var buttonStyle = new Style(typeof(Button));
// Set the properties of the style
buttonStyle.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(purple)));
buttonStyle.Setters.Add(new Setter(Control.ForegroundProperty, new SolidColorBrush(white)));
buttonStyle.Setters.Add(new Setter(Control.BorderBrushProperty, new LinearGradientBrush(purple, salmon, 45d)));
buttonStyle.Setters.Add(new Setter(Control.BorderThicknessProperty, new Thickness(5)));
// Set this style as a resource. Any DynamicResource tied to this key will be updated.
this.Resources["buttonStyle1"] = buttonStyle;
// Set this style directly to a button
((Button)sender).Style = buttonStyle;
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
'Create colors
Dim purple = DirectCast(ColorConverter.ConvertFromString("#4E1A3D"), Color)
Dim white = Colors.White
Dim salmon = Colors.Salmon
'Create a new style for a button
Dim buttonStyle As New Style()
'Set the properties of the style
buttonStyle.Setters.Add(New Setter(Control.BackgroundProperty, New SolidColorBrush(purple)))
buttonStyle.Setters.Add(New Setter(Control.ForegroundProperty, New SolidColorBrush(white)))
buttonStyle.Setters.Add(New Setter(Control.BorderBrushProperty, New LinearGradientBrush(purple, salmon, 45D)))
buttonStyle.Setters.Add(New Setter(Control.BorderThicknessProperty, New Thickness(5)))
'Set this style as a resource. Any DynamicResource looking for this key will be updated.
Me.Resources("buttonStyle1") = buttonStyle
'Set this style directly to a button
DirectCast(sender, Button).Style = buttonStyle
End Sub
代码运行后,窗口将更新:
应用样式于按钮后出现的窗口
请注意,第四个按钮的样式已更新。 该样式会自动应用,因为该按钮使用了 DynamicResource 标记扩展 引用尚不存在的样式。 创建样式并将其添加到窗口的资源后,该样式将应用于该按钮。 有关详细信息,请参阅 动态资源。
查找资源
以下代码遍历运行中的 XAML 对象的逻辑树,以查找指定的资源。 资源可能在对象本身、它的父对象、一直到根部乃至整个应用程序上定义。 以下代码从按钮本身开始搜索资源:
myButton.Style = myButton.TryFindResource("buttonStyle1") as Style;
myButton.Style = myButton.TryFindResource("buttonStyle1")
显式引用资源
当您通过搜索或创建引用到一个资源时,可以直接将其分配给一个属性:
// Set this style as a resource. Any DynamicResource tied to this key will be updated.
this.Resources["buttonStyle1"] = buttonStyle;
'Set this style as a resource. Any DynamicResource looking for this key will be updated.
Me.Resources("buttonStyle1") = buttonStyle