Создание библиотеки ресурсов

  • Командой меню File/Add/New Project оболочки добавьте к решению новый проект DLL -библиотеки с именем LibraryResource по шаблону WPF Custom Control Library


увеличить изображение

  • В панели Solution Explorer переименуйте файл с дежурным именем CustomControl1.cs в CustomResources.cs
  • Откройте файл CustomResources.cs на редактирование, ознакомтесь с инструкцией подключения библиотеки к исполнимой сборке и удалите ее из файла, чтобы не заслоняла будущий код
  • Полностью удалите из класса CustomResources статический конструктор, который в данной задаче нам не пригодится (или не удаляйте, пусть болтается как есть)
using System;using System.Collections.Generic;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes; namespace LibraryResource{ public class CustomResources : Control { /* // Статический конструктор в данной задаче не используется static CustomResources() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomResources), new FrameworkPropertyMetadata(typeof(CustomResources))); } //*/ }}
  • Наполните класс CustomResources следующим кодом, определяющим ключи доступа к ресурсам
namespace LibraryResource{ public class CustomResources : Control { // Статические поля (для разнообразия) public static readonly ComponentResourceKey Title1Key = new ComponentResourceKey(typeof(CustomResources), "Title1"); public static readonly ComponentResourceKey Title2Key = new ComponentResourceKey(typeof(CustomResources), "Title2"); // Добавили флаг для регулирования извлечения в элементах разметки public static bool changeResourceKeyFlag = true; // Добавляем статические свойства public static ComponentResourceKey ForegroundBrushKey { get { if (changeResourceKeyFlag) return new ComponentResourceKey( typeof(CustomResources), "ForegroundBrush1"); else return new ComponentResourceKey( typeof(CustomResources), "ForegroundBrush2"); } } public static ComponentResourceKey BackgroundBrushKey { get { if (changeResourceKeyFlag) return new ComponentResourceKey( typeof(CustomResources), "BackgroundBrush1"); else return new ComponentResourceKey( typeof(CustomResources), "BackgroundBrush2"); } } }}
  • В автоматически созданной папке Themes откройте файл Generic.xaml и удалите из него заготовку контейнера <Style>...</Style> (имя файла зарезервировано и его менять нельзя!)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LibraryResource"> <Style TargetType="{x:Type local:CustomResources}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:CustomResources}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style></ResourceDictionary>

Обратите внимание, что мастер оболочки автоматически сгенерировал оператор подключения пространства имен нашей библиотеки к разметке с псевдонимом local. Мы вольны изменить этот префикс на любой другой, но делать это ни к чему и будем в далнейшем использовать именно его для доступа к статическим свойствам класса CustomResources при определении наших ресурсов.

  • Наполните ресурсный словарь <ResourceDictionary>...</ResourceDictionary> следующей разметкой определения ресурсов (окончательная разметка файла Generic.xaml приводится полностью)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LibraryResource"> <TextBlock x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=Title1}" TextAlignment="Center" Text="Группа кнопок 1" FontSize="14" FontWeight="Bold" FontFamily="Arial" FontStyle="Italic" TextDecorations="Underline" Foreground="DarkViolet" /> <SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=ForegroundBrush1}" Color="Blue" /> <ImageBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=BackgroundBrush1}" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 10 10" ImageSource="Images/FACE02.ICO" Opacity="0.5" /> <TextBlock x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=Title2}" TextAlignment="Center" Text="Группа кнопок 2" FontSize="14" FontWeight="Bold" FontFamily="Arial" FontStyle="Italic" TextDecorations="Underline" Foreground="DarkViolet" /> <SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=ForegroundBrush2}" Color="Red" /> <ImageBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources}, ResourceId=BackgroundBrush2}" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 24 24" ImageSource="Images/FACE04.ICO" Opacity="0.3" /></ResourceDictionary>

В приведенной разметке мы использовали такие же ресурсы, что и в первом упражнении, чтобы не слишком напрягаться. Обратите внимание на новый синтаксис определения ключа. В атрибутах расширения разметки указана вся необходимая информация для синтаксического анализатора. Она указывает, в каком классе искать статическое свойство идентификатора ресурса и в каком пространстве имен текущей библиотечной сборки находится этот класс (об этом сообщает префикс).

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

  • В панели Solution Explorer вызовите контекстное меню для проекта LibraryResource и выполните команду Build (или Rebuild ), чтобы откомпилировать проект и создать библиотечную сборку. Эта сборка неисполнимая, поэтому запускать проект на выполнение не следует, компилятор все равно выдаст ошибку
  • В панели Solution Explorer выделите узел проекта LibraryResource и щелкните на пиктограмме Show All Files этой панели для раскрытия дерева файлов проекта

 

Мы видим, что оболочка откомпилировала проект и создала библиотечную сборку LibraryResource.dll, которую теперь можно использовать вместе с любой исполнимой сборкой для извлечения заложенных в нее ресурсов. Разумеется, в промышленных проектах следующим шагом следовало бы написать подробную инструкцию к пользованию этой библиотекой (выпустить документацию - почти как MSDN ), но мы этого делать не будем.