04_Березина_Object_Resources

advertisement
Ресурсы WPF
 Два типа ресурсов WPF:
• объектные ресурсы (object resource) – определенный .NET-объект, который можно
использовать многократно;
• ресурсы сборки ( assembly resource) – двоичные данные, встроенные в
скомпилированную сборку.
Объектные ресурсы WPF
 WPF ресурсы (объектные ресурсы) – простой способ повторного использования
определенных объектов и их значений. Ресурсы можно создавать и использовать как в
разметке, так и в коде.
 Любой элемент, производный от FrameworkElement или FrameworkContentElement,
содержит коллекцию ResourceDictionary, которая доступна через свойство Resources.
public ResourceDictionary Resources { get; set; }
 Класс ResourceDictionary реализует интерфейс IDictionary, его внутренняя реализация
использует класс Hashtable. Ресурсы хранятся в коллекции в виде пар ключ-значение.
Обычно ключ - это строка, но можно использовать и другие типы.
 Каждый ресурс в коллекции ResourceDictionary должен иметь уникальный ключ:
• при определении ресурса в разметке уникальный ключ определяется через атрибут
x:KeyAttribute;
• при определении ресурса в коде ключ указывается как параметр метода Add.
 Можно определить ресурсы в любом элементе. Дочерний элемент имеет доступ к
любому ресурсу, определенному в любом из родительских элементов. По этой причине
ресурсы обычно определяются в корневом элементе окна, страницы или приложения.
 Свойство Resources возвращает только словарь ресурсов, объявленный
непосредственно внутри данного элемента.
Пример определения ресурса в разметке
 В примере два контекстных меню объявлены как ресурсы в элементе Window - одно с
ключом “key_Russian_Menu”, другое с ключом “key_English_Menu”.
 Ресурс с ключом “key_Russian_Menu” используется как значение для свойства
ContextMenu элемента listBox1.
<Window x:Class="Wpf_Resources.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="394" Width="527" Loaded="Window_Loaded">
<Window.Resources>
<ContextMenu x:Key="key_Russian_Menu">
<MenuItem Header="Добавить" Click="Add_Click"></MenuItem>
<MenuItem Header="Добавить список" Click="Defaults_Click"></MenuItem>
</ContextMenu>
<ContextMenu x:Key="key_English_Menu">
<MenuItem Header="Add" Click="Add_Click"></MenuItem>
<MenuItem Header="Add Defaults" Click="Defaults_Click"></MenuItem>
</ContextMenu>
</Window.Resources>
<Grid Height="343">
<ListBox Margin="10,50,10,10" Name="listBox1"
ContextMenu="{StaticResource key_Russian_Menu}">
</ListBox>
</Grid>
</Window>
Объект пользовательского типа как ресурс
 В примере два объекта типа CustomData.Data_1 объявлены как ресурсы в объекте
Application - один с ключом “datakey_1”, другой с ключом “datakey_2”. При создании
объектов для их инициализации будут вызваны конструкторы без параметров.
 Пространство имен CustomData объявлено в открывающем тэге элемента Application с
префиксом zz. Префикс zz используется в элементах разметки, объявляющих объекты
типа Data_1.
<Application x:Class="Wpf_Resources.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:zz="clr-namespace:Custom_Data"
StartupUri="Window1.xaml">
<Application.Resources>
<zz:Data_1 x:Key="datakey_1"> </zz:Data_1>
<zz:Data_1 x:Key="datakey_2"> </zz:Data_1>
</Application.Resources>
</Application>
Работа с объектными ресурсами в коде
 Класс FrameworkElement содержит методы для поиска ресурса
public Object FindResource ( Object resourceKey );
public Object TryFindResource( Object resourceKey );
 Оба метода возвращают ссылку на ресурс с заданным ключом, если ключ найден. Если
ресурс не найден, метод FindResource бросает исключение, а метод TryFindResource
возвращает null.
 В примере в обработчике English_Checked (события Checked радиокнопки) выполняется
поиск ресурса с ключом “key_English_Menu”. Если ресурс найден и может быть приведен к
типу ContextMenu, он используется как значение свойства ContextMenu для ListBox1.
private void English_Checked(object sender, RoutedEventArgs e)
{
ContextMenu menu = listBox1.TryFindResource("key_English_Menu") as ContextMenu;
if (menu != null) listBox1.ContextMenu = menu;
}
Статические и динамические ресурсы WPF
После того, как ресурс определен, на него можно ссылаться как в разметке, так и в коде.
 Ресурс можно использовать как статический или динамический. В разметке определены
расширения StaticResource или DynamicResource.
 При обработке StaticResource просматриваются доступные словари ресурсов. Это
происходит в процессе загрузки, в тот момент, когда свойству необходимо присвоить
значение из статических ресурсов.
 При обработке DynamicResource ключ создает выражение, которое вычисляется только
в процессе выполнения приложения, и тогда на его основе формируется значение.
 Синтаксический анализ ресурсов выполняется асинхронно. Ресурс, определенный в
XAML , может быть не доступен даже в обработчике события Loaded для элемента, в
котором он определен.
 Доступ к ресурсам из кода эквивалентен ссылке DynamicResource в XAML.
Cтатические ресурсы WPF
 В поисках необходимого ключа для статического ресурса словари ресурсов
просматриваются в следующем порядке:
• словарь, определенный в элементе, для которого устанавливается свойство;
• словари логического дерева элементов в направлении к родительскому элементу
вплоть до корневого элемента;
• словарь объекта Application.
 Словари просматриваются в процессе загрузки, в тот момент, когда свойству
необходимо присвоить значение из статических ресурсов.
 Опережающие ссылки (forward reference) не поддерживаются статическими ресурсами.
Внутри самого словаря ресурсов ссылку можно сделать только на ранее определенный
ресурс.
Использование статических ресурсов WPF
 Статические ресурсы рекомендуется использовать в следующих случаях:
• Значение ресурса не изменяется после того, как на него была сделана ссылка в
первый раз.
• Дизайн приложения концентрирует большую часть своих ресурсов в словарях
уровня страниц или приложения и ссылки на ресурсы не вычисляются на основе
поведения времени выполнения, например, при загрузке страниц.
• Статический ресурс можно использовать, чтобы присвоить значение свойству,
которое не является свойством зависимостей.
• Можно создать словарь ресурсов и скомпилировать его в DLL для повторного
использования.
• Ресурс используется для того, чтобы установить большое число свойств
зависимостей. Свойства зависимостей имеют поддержку для эффективного
кэширования, и в случае, когда значение свойства зависимости можно вычислить
при загрузке, использование статических ресурсов повышает эффективность
приложения.
Использование динамических ресурсов WPF
 В следующих случаях используются динамические ресурсы:
• Значение зависит от параметров, которые станут известны только в период
выполнения, например, есть ссылки на значения SystemColors, SystemFonts или
SystemParameters.
• Словарь ресурсов изменяется во время работы приложения.
• Ресурсы имеет внутренние связи, использующие опережающие ссылки (forward
reference), которые не поддерживаются статическими ресурсами.
• Используется большой ресурс, который может быть запрошен не сразу после
загрузки. В отличие от статических ресурсов, динамические ресурсы не загружаются
до тех пор, пока не будут использованы.
• Создается стиль (style), в котором устанавливаются значения , зависящие от других
установок пользователя.
• Ресурс используется элементом, для которого в процессе жизни приложения может
быть заменен родительский элемент, что возможно изменяет область поиска ресурса.
Download