Упражнение 2. Использование ресурсов как статических свойств и полей классов
Механизм доступа к ресурсам построен таким образом, что ресурсы можно создавать в обычном классе, а затем по мере надобности извлекать их оттуда. Это относится как к пользовательским, так и к библиотечным классам.
В WPF заготовлены 3 специальных библиотечных класса, хранящие наиболее востребованные ресурсы. Это классы SystemColors, SystemFonts и SystemParameters - все они находятся в пространстве имен System.Windows сборки PresentationFramework.dll и являются частью WPF. В пространстве имен System.Drawing тоже имеются одноименные классы SystemColors и SystemFonts, но они относятся к технологии Windows Forms и никакого отношения к рассматриваемым ресурсам не имеют.
Тот механизм хранения и извлечения ресурсов, который мы здесь будем применять, основан на использовании статических свойств и статических полей классов. Существует и другой подход к решению подобной задачи - хранение и извлечение свойств и полей экземпляров классов. Но такой способ относится к теме привязки данных и в этом разделе рассматриваться не будет.
Ключевым компонентом в месте извлечения статического свойства или поля является служебное слово x:Static, настраивающее синтаксический анализатор на поиск такого ресурса. В предыдущем упражнении мы уже подобным синтакисом пользовались для извлечения системного цвета при определении кисти в ресурсе файла App.xaml так
<!-- Определение ресурсов в коллекции приложения --> <Application.Resources> <SolidColorBrush x:Key="ControlColorBrush" Color="{x:Static SystemColors.ControlColor}" /> </Application.Resources>Присоединение ресурса кисти к целевому элементу в файле Window1.xaml мы задали в синтаксисе расширения разметки так
<Window x:Class="UseResource.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="UseResource" MinHeight="300" MinWidth="300" Height="300" Width="300" Background="{StaticResource ControlColorBrush}"> ...............................................</Window>Если посмотреть свойства любого из классов SystemColors, SystemFonts или SystemParameters, то они существуют парами: одно свойство представляет объект, а парное свойство представляет ключ с добавкой Key. Например, MenuBarBrush и MenuBarBrushKey. Все свойства с окончанием Key возвращают объект ключа типа ComponentResourceKey. Соответственно, существуют и два синтаксиса: извлечение самого объекта и извлечение объекта по ключу.
Извлекаемое статическое свойство или поле должны соответствовать по типу целевому элементу так, чтобы синтаксический анализатор мог легко их конвертировать. Если свойство представляет нужный тип, то его сразу можно использовать без предварительного размещения в коллекции ресурсов окна. Так например, цвет фона окна можно сразу задать одним из следующих способов (все способы эквивалентны)
<Window .................................................... Background="{x:Static SystemColors.MenuBarBrush}" > ....................................................</Window><Window .................................................... Background="{DynamicResource {x:Static SystemColors.MenuBarBrushKey}}" > ....................................................</Window><Window .................................................... > <Window.Background> <x:Static Member="SystemColors.MenuBarBrush" /> </Window.Background> ....................................................</Window><Window .................................................... > <Window.Background> <DynamicResourceExtension> <DynamicResourceExtension.ResourceKey> <x:Static Member="SystemColors.MenuBarBrushKey" /> </DynamicResourceExtension.ResourceKey> </DynamicResourceExtension> </Window.Background> ....................................................</Window>Извлекать можно не только статические поля и свойства упомянутых классов WPF, но и любых библиотечных классов, подходящих по типу целевому элементу. Но если применяются классы, не принадлежащие WPF, то соответствующее пространство имен и сборку нужно отобразить на разметку, использовав произвольный псевдоним (префикс). Долее этот префикс будет ассоциировать с пространством имен класса, в котором находятся статические поля или свойства. При использовании нескольких пространств имен и сборок, не принадлежащих WPF, все их нужно указать, чтобы у синтаксического анализатора не было проблем с видимостью классов. Например
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:custom1="clr-namespace:System;assembly=mscorlib" xmlns:custom2="clr-namespace:MyNamespace" ................................................. > .................................................</Window>Продемонстрируем сказанное на простом приложении.
- Добавьте к решению командой File/Add/New Project новый проект типа WPF Application с именем UseStaticMember и назначьте его стартовым
- Заполните файл Window1.xaml следующим исходным кодом разметки
- Добавьте в открывающий дескриптор окна библиотечный ресурс (объект) определения параметра цвета фона по синтаксису расширения разметки
- Добавьте в открывающий дескриптор компоновочной панели код определения префиксов пространств имен системной сборки и сборки текущего проекта (для текущего проекта сборку можно не указывать, если ее имя совпадает с пространством имен)
- Поместите в компоновочную панель файла Window1.xaml следующий код разметки (файл приводится полностью)
- В застраничном файле процедурного кода Window1.xaml.cs создайте класс с именем UserClass и определите в нем статические члены (static members) следующим образом (файл приводится полностью)
- Запустите приложение - результат будет следующим
К приведенному коду следует сделать несколько замечаний.