Bewerken

Delen via


How to define and reference a WPF resource (WPF .NET)

This example shows how to define a resource and reference it. A resource can be referenced through XAML or through code.

XAML example

The following example defines two types of resources: a SolidColorBrush resource, and several Style resources.

<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>

Resources

The SolidColorBrush resource MyBrush is used to provide the value of several properties that each take a Brush type value. This resource is referenced through the x:Key value.

<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>

In the previous example, the MyBrush resource is accessed with the StaticResource Markup Extension. The resource is assigned to a property that can accept the type of resource being defined. In this case the Background, Foreground, and Fill properties.

All resources in a resource diction must provide a key. When styles are defined though, they can omit the key, as explained in the next section.

Resources are also requested by the order found within the dictionary if you use the StaticResource Markup Extension to reference them from within another resource. Make sure that any resource that you reference is defined in the collection earlier than where that resource is requested. For more information, see Static resources.

If necessary, you can work around the strict creation order of resource references by using a DynamicResource Markup Extension to reference the resource at runtime instead, but you should be aware that this DynamicResource technique has performance consequences. For more information, see Dynamic resources.

Style resources

The following example references styles implicitly and explicitly:

<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>

In the previous code example, the Style resources TitleText and Label, each target a particular control type. In this case, they both target a TextBlock. The styles set a variety of different properties on the targeted controls when that style resource is referenced by its resource key for the Style property.

The style though that targets a Border control doesn't define a key. When a key is omitted, the type of object being targeted by the TargetType property is implicitly used as the key for the style. When a style is keyed to a type, it becomes the default style for all controls of that type, as long as these controls are within scope of the style. For more information, see Styles, DataTemplates, and implicit keys.

Code examples

The following code snippets demonstrate creating and setting resources through code

Create a style resource

Creating a resource and assigning it to a resource dictionary can happen at any time. However, only XAML elements that use the DynamicResource syntax will be automatically updated with the resource after it's created.

Take for example the following Window. It has four buttons. The forth button is using a DynamicResource to style itself. However, this resource doesn't yet exist, so it just looks like a normal button:

<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>

A window before a style is applied to a button

The following code is invoked when the first button is clicked and performs the following tasks:

  • Creates some colors for easy reference.
  • Creates a new style.
  • Assigns setters to the style.
  • Adds the style as a resource named buttonStyle1 to the window's resource dictionary.
  • Assigns the style directly to the button raising the Click event.
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

After the code runs, the window is updated:

A window after a style is applied to a button

Notice that the forth button's style was updated. The style was automatically applied because the button used the DynamicResource Markup Extension to reference a style that didn't yet exist. Once the style was created and added to the resources of the window, it was applied to the button. For more information, see Dynamic resources.

Find a resource

The following code traverses the logical tree of the XAML object in which is run, to find the specified resource. The resource might be defined on the object itself, it's parent, all the way to the root, the application itself. The following code searches for a resource, starting with the button itself:

myButton.Style = myButton.TryFindResource("buttonStyle1") as Style;
myButton.Style = myButton.TryFindResource("buttonStyle1")

Explicitly reference a resource

When you have reference to a resource, either by searching for it or by creating it, it can be assigned to a property directly:

// 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

See also