Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Windows Presentation Foundation.docx
Скачиваний:
12
Добавлен:
13.08.2019
Размер:
1.13 Mб
Скачать

12. Ресурсы

Платформа .NETподдерживает инфраструктуру для работы с ресурсами – информационными фрагментами приложения, представляющими изображения, таблицы строк или иные данные. WPFрасширяет базовые возможности .NET, предоставляя поддержку двух видов ресурсов – двоичных и логических.

Двоичные ресурсы

Двоичный ресурс в WPF – это традиционный ресурс с точки зрения платформы .NET. Обычно на этапе разработки двоичный ресурс представлен в виде файла в составе проекта. Такой файл может быть внедрён в сборку .NETили существовать в виде отдельного компонента, логически связанного со сборкой. Это поведение настраивается в VisualStudioв окне свойств файла. Установите BuildActionвзначение Resource для внедрения ресурса, или в Content для закрепления ассоциации между отдельным файлом ресурса и сборкой.

Для доступа к двоичным ресурсам WPFобычно использует универсальный идентификатор ресурса в формате упакованного URI1 (этот синтаксис закреплён в стандарте XPS).Упакованный URIимеет вид pack://контейнер/путь. Ниже представлены некоторые типичные примеры упакованныхURI.

  • pack://application:,,,/img.png – ресурс img.png (изображение), внедрённый в текущую сборку, или файл img.png, ассоциированный со сборкой при компиляции.

  • pack://application:,,,/sub/img.png – аналогично предыдущему, но в проекте Visual Studio файл img.png располагался в подкаталогеsub.

  • pack://application:,,,/Assembly_2;component/img.png – ресурсimg.png, внедрённыйвсборкуAssembly_2.dll.

  • sub/img.png – относительный упакованный URI для ссылки на ресурс, связанный с текущей сборкой.

Для работы с упакованнымиURIимеется класс System.Uri. Вот пример связывания элемента Imageс изображением, представленным в виде ресурса:

// этотобъектописываетабсолютныйURI

var absoluteUri = newUri("pack://application:,,,/images/img.png");

// этотобъектописываетотносительныйURI

var relativeUri = newUri("images/img.png", UriKind.Relative);

// создадимэлементImage

var picture = newImage();

// свяжемImageсbitmap-изображением, используяабсолютныйURI

picture.Source = newBitmapImage(absoluteUri);

В разметке XAML ссылки на ресурсы обычно задаются простыми строками, так как имеется конвертер типов «строка–объект URI»:

<Image x:Name="img" Source="images/img.png" />

Логические ресурсы

Логические (объектные) ресурсы – это произвольные объекты, ассоциированные с элементом WPF. Классы FrameworkElement и FrameworkContentElement определяют словарь Resources с типом System.Windows.ResourceDictionary. Этот словарь хранит коллекцию логических ресурсов элемента. С коллекцией Resources можно работать как в коде, так и в разметке XAML.В последнем случае объект, помещаемый в ресурс, должен обладать конструктором без параметров. Кроме этого, для определения ключа словаря в разметке требуется использовать атрибут x:Key из пространства имён анализатора XAML:

<!-- Определение ресурсов для кнопки в XAML-->

<Button x:Name="btn" Content="OK">

<Button.Resources>

<SolidColorBrush x:Key="background">

Yellow

</SolidColorBrush>

<SolidColorBrush x:Key="borderBrush">

Red

</SolidColorBrush>

</Button.Resources>

</Button>

// эквивалентное определение ресурсов для кнопки в коде

btn.Resources.Add("background", newSolidColorBrush(Colors.Yellow));

btn.Resources.Add("borderBrush", newSolidColorBrush(Colors.Red));

Чтобы сослаться на ресурс в разметке XAML, необходимо использовать расширения разметки {StaticResource} или {DynamicResource}.При этом указывается ключ ресурса. Анализатор XAML выполняет поиск ресурса по ключу, просматривая коллекцию ресурсов элемента, затем ресурсы родительского элемента, и так далее. Вот почему ресурсы обычно объявляются на уровне родительского окна или объекта Application.

<Window xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

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

<Window.Resources>

<SolidColorBrush x:Key="borderBrush">Red</SolidColorBrush>

</Window.Resources>

<Button Content="OK" BorderBrush="{StaticResource borderBrush}"/>

</Window>

При статической ссылке изменения ресурса после применения не влияют на целевой объект. При динамическом использовании любая модификация ресурса (даже после применения!) отразится на целевом объекте. Ниже показан пример статического и динамического применения ресурсов в коде:

// статическое применение ресурса с поиском по дереву элементов

button.Background = (Brush)button.FindResource("background");

// статическое применение ресурса из заданной коллекции ресурсов

button.Background = (Brush)window.Resources["background"];

// динамическоеприменениересурса

button.SetResourceReference(Button.BackgroundProperty, "background");

Определение логических ресурсов часто выносится в отдельныйXAML-файл, который в качестве корневого элемента содержит <ResourceDictionary>:

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

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

<Image x:Key="logo" Source="logo.jpg"/>

</ResourceDictionary>

ДлятогочтобыобъединитьресурсывфайлахсколлекциейResources, следуетиспользоватьсвойствоMergedDictionariesклассаResourceDictionary:

<Window.Resources>

<ResourceDictionary>

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="file1.xaml"/>

<ResourceDictionary Source="file2.xaml"/>

</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

</Window.Resources>