Использование ресурсов
98WPF --- Элементы управления WPF --- Использование ресурсов
Упакованные URI
WPF позволяет обращаться к скомпилированным ресурсам (вроде BAML-файла для страницы) с помощью синтаксиса упакованных URI (pack URI). В предыдущей статье в элементе Image и дескрипторе для ссылки на ресурс использовался относительный URI:
images/winter.jpg
Эквивалентный ему более громоздкий абсолютный URI показан ниже:
pack://application:,,,/images/winter.jpg
Такой абсолютный URI можно использовать при установке источника изображения, хотя никаких дополнительных преимуществ это не даст.
В случае применения абсолютного URI можно использовать путь к файлу, UNC-путь к сетевому ресурсу, URL-адрес веб-сайта или упакованный URI, указывающий на ресурс сборки. Главное помнить о том, что если приложению не удастся извлечь ресурс из указанного места, сгенерируется исключение. Если URI был установлен в XAML, исключение сгенерируется на этапе создания страницы.
Синтаксис упакованного URI был позаимствован из стандарта XPS (XML Paper Specification). Причина его странного внешнего вида заключается в том, что он подразумевает вставку одного URI внутрь другого. Три запятых фактически представляют собой три отмененных косых черты. Другими словами, показанный выше упакованный URI содержит URI приложения, начинающийся с конструкции application://.
Ресурсы в других сборках
Упакованные URI также позволяют извлекать ресурсы, находящиеся в другой библиотеке (другими словами, в DLL-сборке, которую использует приложение). В таком случае должен использоваться следующий синтаксис:
pack://application:,,,/AssemblyName;component/ResourceName
Например, если изображение находится в ссылаемой сборке по имени ImageLibrary, потребуется использовать такой URI:
img.Source = new BitmapImage(
new Uri("pack://application:,,,/ImageLibrary;component/images/winter.jpg"));
Если применяется сборка со сложным именем, имя сборки можно заменить уточненной ссылкой на сборку, включающей версию, маркер открытого ключа либо то и другое вместе. Каждый фрагмент информации следует отделить точкой с запятой, а перед номером версии добавить букву v. Ниже показан пример:
img.Source = new Bitmaplmage(
new Uri("ImageLibrary;vl.25;dc642a7f5bd64912;component/images/winter.jpg",
UnKind.Relative));
Файлы содержимого
При добавлении файла в виде ресурса его следует поместить в скомпилированную сборку и удостовериться в том, что он будет доступен всегда. Такой подход является идеальным вариантом для развертывания и исключает возможные проблемы. Однако в некоторых ситуациях он непрактичен, а именно:
при желании изменить файл ресурса без повторной компиляции приложения;
когда файл ресурса имеет очень большой размер;
когда файл ресурса является необязательным и может не развертываться со сборкой;
когда ресурс представляет собой звуковой файл.
Звуковые классы WPF не поддерживают ресурсов сборки. По этой причине способа для извлечения аудиофайла из потока ресурсов и его воспроизведения не существует — по крайней мере, без его предварительного сохранения. Таково ограничение лежащих в основе технологии компонентов, на которых основаны данные классы (а именно — интерфейса Win32 API и проигрывателя Media Player).
Очевидно, что обойти эту проблему можно путем развертывания файлов вместе с приложением и добавления в приложение соответствующего кода для чтения этих файлов с жесткого диска. Однако WPF имеет удобную опцию, которая может упрощать выполнение этого процесса и заключается в специальной маркировке таких не скомпилированных файлов как файлов содержимого.
Файлы содержимого в сборку не встраиваются. Тем не менее, WPF добавляет к сборке атрибут AssemblyAssociatedContentFile, который объявляет о существовании каждого файла содержимого. Этот атрибут также записывает информацию о размещении каждого файла содержимого по отношению к исполняемому файлу (показывая, находится ли файл содержимого в той же папке, что и исполняемый файл, или же в отдельной подпапке). Лучше всего то, что для использования файлов содержимого с элементами, умеющими работать с ресурсами, можно применять ту же самую систему URI.
Чтобы проверить это, добавьте в свой проект какой-то звуковой файл, выделите его в окне Solution Explorer и измените значение свойства Build Action в окне Properties на Content (содержимое). Удостоверьтесь в том, что для параметра Copy to Output Directory (Копировать в выходной каталог) установлено значение Copy Always (Копировать всегда), чтобы звуковой файл копировался в каталог вывода при компоновке проекта.
Теперь можно использовать относительный URI, чтобы указать MediaElement на свой файл содержимого:
<MediaElement Name="Sound" Source="Sounds/start.wav"
LoadedBehavior="Manual"></MediaElement>