
- •Ресурсы в wpf
- •Упражнение 1. Использование коллекций ресурсов
- •Размещение ресурсов в коллекции окна
- •Размещение ресурсов в отдельных файлах
- •Задание к упражнению
- •Упражнение 2. Использование ресурсов как статических свойств и полей классов
- •Упражнение 3. Хранение ресурсов в пользовательской библиотеке
- •Создание библиотеки ресурсов
- •Использование библиотеки ресурсов
Размещение ресурсов в отдельных файлах
В приведенной разметке мы определили ресурсы в коллекции ресурсов окна, затем извлекаем их как в элементах интерфейса декларативно, так и программно в процедурном коде. Но ресурсы можно выносить в отдельные файлы и использовать не только в одном, но во множестве проектов. Эта возможность достижима с помощью применения ресурсных словарей. Ресурсный словарь - это независимая коллекция ресурсов в отдельном файле XAML, которую можно импортировать в коллекцию Resources любого элемента приложения WPF.
Продемонстрируем применение ресурсного словаря в нашем приложении. Вынесем определение ресурсов в отдельный файл и подключим этот файл к коллекции ресурсов окна.
В панели Solution Explorer выделите корень проекта UseResource и командой Project/Add Resource Dictionary создайте файл с именем ResBrushes1.xaml
увеличить изображение
Перенесите (вырезать в одном, вставить в другом) в контейнер <ResourceDictionary> из файла Window1.xaml определенное там ранее содержимое контейнера <Window.Resources>, чтобы файл ResBrushes1.xaml стал таким
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock x:Key="Title1"
TextAlignment="Center"
Text="1. Модификация объекта ресурса"
FontSize="14" FontWeight="Bold"
FontFamily="Arial"
FontStyle="Italic"
TextDecorations="Underline"
Foreground="DarkViolet"
/>
<SolidColorBrush x:Key="ForegroundBrush1"
Color="Blue" />
<ImageBrush x:Key="BackgroundBrush1"
TileMode="Tile"
ViewportUnits="Absolute"
Viewport="0 0 10 10"
ImageSource="Images/FACE02.ICO"
Opacity="0.5"
/>
<TextBlock x:Key="Title2"
TextAlignment="Center"
Text="2. Полная замена объекта ресурса"
FontSize="14"
FontWeight="Bold"
FontFamily="Arial"
FontStyle="Italic"
TextDecorations="Underline"
Foreground="DarkViolet"
/>
<SolidColorBrush x:Key="ForegroundBrush2"
Color="Red"
/>
<ImageBrush x:Key="BackgroundBrush2"
TileMode="Tile"
ViewportUnits="Absolute"
Viewport="0 0 24 24"
ImageSource="Images/FACE04.ICO"
Opacity="0.3"
/>
</ResourceDictionary>
Теперь осталось подключить файл ресурсов ResBrushes1.xaml к контейнеру ресурсов окна Window1.xaml.
Добавьте в контейнер <Window.Resources> файла Window1.xaml следующий код разметки
<!-- Определение ресурсов в коллекции окна -->
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResBrushes1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Запустите приложение - оно работает как и прежде, как будто бы мы и не переносили ресурсы во внешний файл
Рассмотренный прием позволяет размещать ресурсы не только в одном, но и в нескольких файлах и использовать их в нужном месте по мере необходимости. Продемонстрируем это.
Выделите корень проекта и добавьте командой Project/Add Resource Dictionary еще один файл с именем ResBrushes2.xaml
Перенесите (вырезать в одном, вставить в другом) из файла ResBrushes1.xaml в контейнер <ResourceDictionary> нового файла ResBrushes2.xaml вторую половину объектов, чтобы содержимое файлов-словарей стало таким
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock x:Key="Title1"
TextAlignment="Center"
Text="1. Модификация объекта ресурса"
FontSize="14" FontWeight="Bold"
FontFamily="Arial"
FontStyle="Italic"
TextDecorations="Underline"
Foreground="DarkViolet"
/>
<SolidColorBrush x:Key="ForegroundBrush1"
Color="Blue" />
<ImageBrush x:Key="BackgroundBrush1"
TileMode="Tile"
ViewportUnits="Absolute"
Viewport="0 0 10 10"
ImageSource="Images/FACE02.ICO"
Opacity="0.5"
/>
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock x:Key="Title2"
TextAlignment="Center"
Text="2. Полная замена объекта ресурса"
FontSize="14"
FontWeight="Bold"
FontFamily="Arial"
FontStyle="Italic"
TextDecorations="Underline"
Foreground="DarkViolet"
/>
<SolidColorBrush x:Key="ForegroundBrush2"
Color="Red"
/>
<ImageBrush x:Key="BackgroundBrush2"
TileMode="Tile"
ViewportUnits="Absolute"
Viewport="0 0 24 24"
ImageSource="Images/FACE04.ICO"
Opacity="0.3"
/>
</ResourceDictionary>
Добавьте в контейнер <Window.Resources> файла Window1.xaml следующий код разметки
<!-- Определение ресурсов в коллекции окна -->
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResBrushes1.xaml" />
<ResourceDictionary Source="ResBrushes2.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Запустите приложение - оно работает как и прежде, как будто бы мы и не распределили ресурсы по отдельным файлам
Переключите редактор файла Window1.xaml в режим Design и убедитесь, что визуальное представление элементов окна совпадает с тем, которое оно имело до вынесения нами ресурсов в отдельные файлы. Значит дизайнер оболочки видит эти ресурсы на этапе проектирования, ну а компилятор их тем более видит!
При добавлении в приложение новых файлов-словарей ресурсов нужно следить за тем, чтобы для них свойство Build Action было установлено в значение Page (такое значение имеют все XAML -файлы). Это гарантирует компиляцию словаря ресурсов для достижения лучшей производительности. Допустимо также значение Resource, но в этом случае ресурс просто встраивается в сборку, но не компилируется. Компиляция такого ресурса происходит только во время выполнения, из-за чего синтаксический анализ в реальном времени немного (незаметно) замедляет работу приложения.