Ресурсы и стили. Подключение внешних ресурсов

Часто ресурсы приложения выносят в отдельные файлы, что позволяет не захламлять исходный код приложения. В WPF мы также можем выносить ресурсы во внешние файлы и подключать их в своих приложениях, а также объединять несколько словарей ресурсов. В этой части мы рассмотрим Подключение внешних ресурсов в WPF.

Файлы ресурсов в WPF

Для примера, воспользуемся приложением из предыдущей части. Напомню, что в этом приложении мы определили ресурс на уровне окна приложения:

<Window.Resources>
    <LinearGradientBrush x:Shared="False" x:Key="MyBrush">
        <GradientStopCollection>
            <GradientStop Color="DarkRed" Offset="0"></GradientStop>
            <GradientStop Color="Red" Offset="0.5"></GradientStop>
            <GradientStop Color="LightPink" Offset="1"></GradientStop>
        </GradientStopCollection>
    </LinearGradientBrush>
</Window.Resources>

Когда ресурсов не много, то можно оставить этот код как есть. Однако, в приложениях могут быть десятки, а то и сотни различных ресурсов, включая и стили оформления элементов управления из-за чего XAML-код страницы или окна приложения может принять нечитаемый вид. Логично вынести ресурсы во внешний файл (или несколько файлов). Например, создадим в проект новую папку Resources:

Теперь добавим в эту папку новый файл с ресурсами. Для этого можно воспользоваться контекстным меню проекта и выбрать элемент «Словарь ресурсов (WPF)»:

В результате, в наш проект добавиться новый файл, содержащий «скелет» словаря ресурсов:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
</ResourceDictionary>

Перенесем в этот файл ресурс из окна приложения:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <LinearGradientBrush x:Shared="False" x:Key="MyBrush">
        <GradientStopCollection>
            <GradientStop Color="DarkRed" Offset="0"></GradientStop>
            <GradientStop Color="Red" Offset="0.5"></GradientStop>
            <GradientStop Color="LightPink" Offset="1"></GradientStop>
        </GradientStopCollection>
    </LinearGradientBrush>
</ResourceDictionary>

При этом, в главном окне кнопка «потеряет» ресурс и станет выглядеть следующим образом:

Чтобы воспользоваться ресурсом из внешнего файла, мы должны воспользоваться подключением файла ресурсов. Рассмотрим подключение файла ресурсов в WPF.

Подключение файла ресурсов

Файлы ресурсов подключаются c использованием ResourceDictionary. Перейдем в файл MainWindow.xaml и изменим его следующим образом:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ResourceDictionary Source="/Resources/Res.xaml"/>
    </Window.Resources>
    <Grid>
        <Button Content="Кнопка"
                Width="200"
                Height="100"
                Background="{StaticResource MyBrush}"
                Click="Button_Click"/>
    </Grid>
</Window>

Обратите внимание на то, как мы подключили внешний файл ресурсов:

<Window.Resources>
    <ResourceDictionary Source="/Resources/Res.xaml"/>
</Window.Resources>
то есть в атрибуте Source мы указываем путь к файлу, содержащему словарь ресурсов. Полученные ресурсы мы, в дальнейшем также используем для кнопки. 

Объединение словарей ресурсов

При необходимости, мы можем объединять различные файлы ресурсов в один словарь. Например, создадим новый файл ресурсов WPF и добавим в него следующий ресурс:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <FontWeight x:Key="ExtraBoldFont">ExtraBold</FontWeight> 
</ResourceDictionary>

Теперь у нас есть два словаря ресурсов:

Если мы попытаемся определить оба словаря так, как в примере выше, то получим ошибку:

<Window.Resources>
     <ResourceDictionary Source="/Resources/Res.xaml"/>
     <ResourceDictionary Source="/Resources/TextStyles.xaml"/>
</Window.Resources>
Свойство «Resources» может быть задано только один раз.

Поэтому мы должны определить в свойстве Resources только один словарь в котором объединить оба файла. Делается это следующим образом:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Resources/Res.xaml"/>
            <ResourceDictionary Source="/Resources/TextStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

Здесь у нас свойство Resources содержит только один словарь у которого в свойстве MergedDictionaries мы указали два внешних файла с ресурсами для объединения. Теперь мы можем воспользоваться всеми ресурсами из этих файлов, например, так:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Resources/Res.xaml"/>
                <ResourceDictionary Source="/Resources/TextStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Content="Кнопка"
                Width="200"
                Height="100"
                FontWeight="{StaticResource ExtraBoldFont}"
                Background="{StaticResource MyBrush}"
                Click="Button_Click"/>
    </Grid>
</Window>

Теперь свойство Background кнопки будет применяться на основе ресурса из файла Res.xaml, а значение свойства FontWeight браться из ресурса в файле TextStyles.xaml

Итого

При необходимости, мы можем выносить ресурсы WPF в отдельные файлы и подключать их в проект, используя свойство ResourceDictionary.Source. Также, в WPF поддерживается объединение словарей ресурсов как расположенных локально, так и в разных сборках.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии