Практическое руководство. Определение и создание ссылки на ресурс WPF (WPF .NET)

В этом примере показано, как определить ресурс и ссылаться на него. На ресурс можно ссылаться средствами языка XAML или с помощью кода.

Важно!

Документация по рабочему столу для .NET 7 и .NET 6 находится в стадии разработки.

Пример 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 и неявные ключи.

Примеры кода

В следующих фрагментах кода демонстрируется создание и настройка ресурсов с помощью кода.

Создание ресурса стиля

В любой момент можно создать ресурс и назначить его словарю ресурсов. Однако после создания ресурса вместе с ним обновляются только элементы XAML, использующие синтаксис DynamicResource.

Возьмем, к примеру, следующее окно. В нем четыре кнопки. Для определения стиля четвертой кнопки используется 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>

A window before a style is applied to a button

Следующий код вызывается при нажатии первой кнопки. Он выполняет следующие задачи:

  • создает некоторые цвета для удобства использования;
  • создает новый стиль;
  • назначает стилю методы задания;
  • добавляет стиль в качестве ресурса с именем 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

После выполнения кода окно обновляется:

A window after a style is applied to a button

Обратите внимание на обновление стиля четвертой кнопки. Стиль был применен автоматически, так как для данной кнопки использовалось расширение разметки 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

См. также