URI типа "pack" в WPF
В Windows Presentation Foundation (WPF), универсальные идентификаторы ресурсов (URI) используются для идентификации и загрузки файлов несколькими способами, включая следующие:
Указание UI для отображения при первом запуске приложения.
Загрузка изображений.
Переход по страницам.
Загрузка неисполняемых файлов данных.
Кроме того URI может использоваться для идентификации и загрузки файлов из различных расположений, включая следующие:
Текущая сборка.
Сборка, на которую добавлена ссылка.
Расположение, связанное со сборкой.
Исходный узел приложения.
Для обеспечения согласованного механизма идентификации и загрузки этих типов файлов из этих расположений, WPF использует расширяемую схему pack URI. В этом разделе представлен обзор схемы, описывается формирование pack URI для разнообразных сценариев, рассматриваются абсолютное и относительное URI, разрешение URI, а также использование pack URI из разметки и кода.
Схема URI типа "pack"
Схема pack URI используется спецификацией Open Packaging Conventions (OPC), которая описывает модель для организации и идентификации содержимого. Основными элементами этой модели являются пакеты и части, где пакет — это логический контейнер для одной или более логических частей. Эта структура показана на следующем рисунке.
Для определения частей спецификация OPC использует расширяемый синтаксис RFC 2396 (Универсальные коды ресурса (URI): Общий синтаксис) для определения схемы pack URI.
Схема URI определяется его префиксом; известные примеры: http, ftp и file. Pack URI использует «pack» в качестве схемы и содержит два компонента: центр и путь. Ниже приведен формат pack URI.
пакет: // центр/путь
Центр указывает тип пакета, в котором находится часть, а путь указывает расположение части внутри пакета.
Эта концепция показана на следующей схеме:
Пакеты и элементы аналогичны приложениям и файлам. Приложение (пакет) может содержать один или несколько файлов (элементов), в том числе:
Файлы ресурсов, скомпилированные в локальную сборку.
Файлы ресурсов, скомпилированные в сборку, на которую указывает ссылка.
Файлы ресурсов, скомпилированные в ссылающуюся сборку.
Файлы содержимого.
Файлы исходного узла.
Для доступа к этим типам файлов, WPF поддерживает два центра: application:///
и siteoforigin:///
. Центр application:///
определяет файлы данных приложения, известные во время компиляции, включая файлы ресурсов и файлы содержимого. Центр siteoforigin:///
определяет файлы исходного узла. На следующем рисунке показана область каждого центра.
Note
Компонент центра pack URI является встроенным URI, указывающим на пакет, и должен соответствовать стандарту RFC 2396. Кроме того, символ "/" необходимо заменить символом ",", и необходимо экранировать такие зарезервированные символы, как "%" и "?". Подробные сведения см. в OPC.
В следующих разделах рассматривается построение pack URI с использованием этих двух центров с соответствующими путями для идентификации ресурсов, содержимого и файлов исходного узла.
URI типа "pack" для файла ресурсов
Файлы ресурсов настраиваются как элемент MSBuild Resource
и компилируются в сборки. WPF поддерживает формирование pack URI, используемых для идентификации файлов ресурсов, которые компилируются либо в локальную сборку, либо в сборку, на которую ссылается локальная сборка.
Файл ресурсов локальной сборки
Pack URI для файла ресурсов, который компилируется в локальную сборку использует следующие центр и путь:
Центр:
application:///
.Путь: Имя файла ресурсов, включая его путь относительно корневой папки проекта локальной сборки.
В следующем примере показан pack URI для XAML файла ресурсов, который находится в корневой папке проекта локальной сборки.
pack://application:,,,/ResourceFile.xaml
В следующем примере показан pack URI для XAML файла ресурсов, который находится во вложенной папке проекта локальной сборки.
pack://application:,,,/Subfolder/ResourceFile.xaml
Файл ресурсов в сборке, на которую добавлена ссылка
Pack URI для файла ресурсов в сборке по ссылке использует следующие центр и путь:
Центр: application:///.
Путь: Имя файла ресурсов, который компилируется в сборку. Путь должен соответствовать следующему формату:
AssemblyShortName{; Версия] {; Открытый ключ]; component /путь
AssemblyShortName — краткое имя для сборки по ссылке.
;Version [необязательно] — версия указанной ссылками сборки, которая содержит файл ресурсов. Используется при загрузке двух или более указанных ссылками сборок с одинаковым кратким именем.
;PublicKey [необязательно]: открытый ключ, который использовался для подписи указанной ссылками сборки. Используется при загрузке двух или более указанных ссылками сборок с одинаковым кратким именем.
;component: указывает, что на упоминаемую сборку ссылается локальная сборка.
/Path: имя файла ресурсов, включая его путь относительно корневой папки проекта указанной ссылками сборки.
В следующем примере показан Pack URI для XAML файла ресурсов, который находится в корневой папке проекта указанной ссылками сборки.
pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml
В следующем примере показан Pack URI для XAML файла ресурсов, который находится во вложенной папке проекта указанной ссылками сборки.
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml
В следующем примере показан Pack URI для XAML файл ресурсов, который находится в корневой папке проекта конкретной версии сборки, указанной ссылкой.
pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml
Обратите внимание, что пакет URI синтаксис для файлов ресурсов указанной ссылками сборки может использоваться только вместе с центром application:///. Например, следующее не поддерживается в WPF.
pack://siteoforigin:,,,/SomeAssembly;component/ResourceFile.xaml
URI типа "pack" для файла содержимого
Pack URI для файла содержимого использует следующие центр и путь:
Центр: application:///.
Путь: Имя файла содержимого, включая его путь относительно расположения файла основной исполняемой сборки приложения.
В следующем примере показано Pack URI для XAML файла содержимого, расположенного в той же папке, что и исполняемая сборка.
pack://application:,,,/ContentFile.xaml
В следующем примере показано Pack URI для XAML файла содержимого, расположенного во вложенной папке относительно исполняемой сборки приложения.
pack://application:,,,/Subfolder/ContentFile.xaml
Note
К HTML файлам содержимого невозможно осуществлять переход. Схема URI поддерживает переход только к HTML файлам, расположенным на исходном узле.
URI типа "pack" исходного узла
Pack URI для исходного узла файла использует следующие центр и путь:
Центр: siteoforigin:///.
Путь: Имя узла исходного файла, включая его путь относительно расположения, из которого была запущена исполняемая сборка.
В следующем примере показан Pack URI для XAML файла исходного узла, хранящегося в расположении, из которого запускается исполняемая сборка.
pack://siteoforigin:,,,/SiteOfOriginFile.xaml
В следующем примере показано Pack URI для XAML файла исходного узла, хранящегося во вложенной папке относительно расположения, из которого запускается исполняемая сборка приложения.
pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml
Файлы страниц
XAML файлы, которые настроены как элемент MSBuild Page
, компилируются в сборки так же, как и файлы ресурсов. Следовательно, элемент MSBuild Page
можно идентифицировать с помощью Pack URI для файлов ресурсов.
Типы XAML файлы, которые обычно настраиваются как элемент MSBuild Page
, имеют один из следующих корневых элементов:
Абсолютные и относительные URI типа "pack"
Полный Pack URI включает в себя схему, центр и путь, и он считается абсолютным Pack URI. Для упрощения разработки XAML элементы обычно допускают настройку соответствующих атрибутов с использованием отноительного Pack URI, который включает только путь.
Например, рассмотрим следующий абсолютный Pack URI для файла ресурсов в локальной сборке.
pack://application:,,,/ResourceFile.xaml
Относительный Pack URI, ссылающийся на этот файл будет следующим.
/ResourceFile.xaml
Note
Поскольку файлы исходного узла не связаны со сборками, на них можно ссылаться только по абсолютному URI.
По умолчанию относительный Pack URI считается относительно расположения разметки или кода, содержащего ссылку. Но если используется обратная косая черта в начале, относительный Pack URI отсчитывается относительно корня приложения. Например, рассмотрим следующую структуру проекта.
App.xaml
Page2.xaml
\SubFolder
+ Page1.xaml
+ Page2.xaml
Если Page1.xaml содержит URI , ссылающийся на корень\SubFolder\Page2.xaml, ссылка может использовать следующий относительный Pack URI.
Page2.xaml
Если Page1.xaml содержит URI , ссылающийся на корень\Page2.xaml, ссылка может использовать следующий относительный Pack URI.
/Page2.xaml
Разрешение URI типа "pack"
Формат Pack URI делает возможным для Pack URI различных типов файлов может выглядеть одинаково. Например, рассмотрим следующий абсолютный Pack URI.
pack://application:,,,/ResourceOrContentFile.xaml
Этот абсолютный Pack URI может ссылаться на файлы ресурсов в локальной сборке или файл содержимого. То же самое верно для следующего относительного URI.
/ResourceOrContentFile.xaml
Чтобы определить тип файла, на который ссылается pack URI, WPF разрешает URI для файлов ресурсов в локальных сборках и файлов содержимого с помощью следующих эвристических методов:
Проверка метаданных сборки на наличие атрибута AssemblyAssociatedContentFileAttribute, соответствующего Pack URI.
Если обнаружен AssemblyAssociatedContentFileAttribute, путь Pack URI ссылается на файл содержимого.
Если AssemblyAssociatedContentFileAttribute не обнаружен, проверить файлы ресурсов, которые компилируются в локальную сборку.
Если файл ресурсов, который соответствует пути Pack URI, найден, путь Pack URI ссылается на файл ресурсов.
Если ресурс не найден, то созданный Uri является недопустимым.
Разрешение URI не применяется для URI, указывающих на следующее:
Файлы содержимого в сборках, указанных ссылками, не поддерживаются WPF.
Внедренные файлы в указанных ссылками сборках: URI, которые их идентифицируют, являются уникальными, поскольку они включают в себя имя сборки, на которые имеются ссылки, и суффикс
;component
.Файлы исходного узла: URI, которые их идентифицируют, являются уникальными, поскольку они являются единственными файлами, которые могут быть идентифицированы pack URI siteoforigin:///.
Единственное упрощение, которое поддерживается pack URI - разрешение URI в некоторой степени независимо от расположения файлов ресурсов и содержимого. Например, если у вас есть файл ресурсов в локальной сборке, который вы затем перенастраиваете в файл содержимого, pack URI для него останется таким же, как и код, который использует этот pack URI.
Программирование с использованием URI типа "pack"
Многие классы WPF реализуют свойства, которые могут быть заданы с помощью pack URI, в том числе:
Эти свойства можно задать из разметки и кода. В этом разделе демонстрируются основные конструкции для разметки и кода, а также приводятся примеры наиболее распространенных сценариев.
Использование URI типа "pack" в разметке
Pack URI задается в разметке путем настройки элемента атрибута с помощью pack URI. Пример:
<element attribute="pack://application:,,,/File.xaml" />
Таблица 1 демонстрирует различные абсолютне Pack URI, которые можно указывать в разметке.
Таблица 1. Абсолютные Pack URI в разметке
Файл | Абсолютный Pack URI |
---|---|
Файл ресурсов — локальная сборка | "pack://application:,,,/ResourceFile.xaml" |
Файл ресурсов в подпапке — локальная сборка | "pack://application:,,,/Subfolder/ResourceFile.xaml" |
Файл ресурсов — указанная ссылками сборка | "pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml" |
Файл ресурсов в подпапке указанной ссылками сборки | "pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml" |
Файл ресурсов в указанной ссылками сборке с несколькими версиями | "pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml" |
Файл содержимого | "pack://application:,,,/ContentFile.xaml" |
Файл содержимого в подпапке | "pack://application:,,,/Subfolder/ContentFile.xaml" |
Файл исходного узла | "pack://siteoforigin:,,,/SOOFile.xaml" |
Файл исходного узла в подпапке | "pack://siteoforigin:,,,/Subfolder/SOOFile.xaml" |
Таблица 2 демонстрирует различные относительные pack URI, которые можно указывать в разметке.
Таблица 2. Относительные Pack URI в разметке
Файл | Относительный Pack URI |
---|---|
Файл ресурсов в локальной сборке | "/ResourceFile.xaml" |
Файл ресурсов в подпапке — локальная сборка | "/Subfolder/ResourceFile.xaml" |
Файл ресурсов в указанной ссылками сборке | "/ReferencedAssembly;component/ResourceFile.xaml" |
Файл ресурсов в подпапке указанной ссылками сборки | "/ReferencedAssembly;component/Subfolder/ResourceFile.xaml" |
Файл содержимого | "/ContentFile.xaml" |
Файл содержимого в подпапке | "/Subfolder/ContentFile.xaml" |
Использование URI типа "pack" в коде
Pack URI можно использовать в коде путем создания экземпляра класса Uri и передачи URI в качестве параметра конструктора. Это показано в следующем примере.
Uri uri = new Uri("pack://application:,,,/File.xaml");
По умолчанию Uri класс считает, что указываемый Pack URI является абсолютным. Следовательно, при создании экземпляра класса Uri с указанием относительного Pack URI возникает исключение.
Uri uri = new Uri("/File.xaml");
К счастью перегрузка Uri(String, UriKind) конструктора Uri принимает параметр типа UriKind, чтобы можно было указать, является ли Pack URI абсолютным или относительным.
// Absolute URI (default)
Uri absoluteUri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute);
// Relative URI
Uri relativeUri = new Uri("/File.xaml",
UriKind.Relative);
Следует указывать Absolute или Relative только когда вы уверены, что указанный Pack URI действительно имеет такой тип. Если вы не знаете тип Pack URI, например, если пользователь вводит его во время выполнения, используйте вместо этого RelativeOrAbsolute.
// Relative or Absolute URI provided by user via a text box
TextBox userProvidedUriTextBox = new TextBox();
Uri uri = new Uri(userProvidedUriTextBox.Text, UriKind.RelativeOrAbsolute);
Таблице 3 показаны различные относительные pack URI, которые можно указать в коде с помощью System.Uri.
Таблица 3. Абсолютные Pack URI в коде
Файл | Абсолютный Pack URI |
---|---|
Файл ресурсов — локальная сборка | Uri uri = new Uri("pack://application:,,,/ResourceFile.xaml", UriKind.Absolute); |
Файл ресурсов в подпапке — локальная сборка | Uri uri = new Uri("pack://application:,,,/Subfolder/ResourceFile.xaml", UriKind.Absolute); |
Файл ресурсов — указанная ссылками сборка | Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Absolute); |
Файл ресурсов в подпапке указанной ссылками сборки | Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Absolute); |
Файл ресурсов в указанной ссылками сборке с несколькими версиями | Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml", UriKind.Absolute); |
Файл содержимого | Uri uri = new Uri("pack://application:,,,/ContentFile.xaml", UriKind.Absolute); |
Файл содержимого в подпапке | Uri uri = new Uri("pack://application:,,,/Subfolder/ContentFile.xaml", UriKind.Absolute); |
Файл исходного узла | Uri uri = new Uri("pack://siteoforigin:,,,/SOOFile.xaml", UriKind.Absolute); |
Файл исходного узла в подпапке | Uri uri = new Uri("pack://siteoforigin:,,,/Subfolder/SOOFile.xaml", UriKind.Absolute); |
Таблица 4 демонстрирует различные относительные pack URI, которые можно указать в коде с помощью System.Uri.
Таблица 4. Относительные Pack URI в коде
Файл | Относительный Pack URI |
---|---|
Файл ресурсов — локальная сборка | Uri uri = new Uri("/ResourceFile.xaml", UriKind.Relative); |
Файл ресурсов в подпапке — локальная сборка | Uri uri = new Uri("/Subfolder/ResourceFile.xaml", UriKind.Relative); |
Файл ресурсов — указанная ссылками сборка | Uri uri = new Uri("/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Relative); |
Файл ресурсов в подпапке — указанная ссылками сборка | Uri uri = new Uri("/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Relative); |
Файл содержимого | Uri uri = new Uri("/ContentFile.xaml", UriKind.Relative); |
Файл содержимого в подпапке | Uri uri = new Uri("/Subfolder/ContentFile.xaml", UriKind.Relative); |
Типичные сценарии использования URI типа "pack"
Предыдущих разделах обсуждались способы создания Pack URI для идентификации ресурсов, содержимого и файлов исходного узла. В WPF эти конструкции используются различными способами, и в следующих разделах описаны некоторые общие способы использования.
Указание пользовательского интерфейса для отображения при запуске приложения
StartupUri указывает первоначальный UI, который должен отображаться при запуске приложения WPF. Для автономных приложений UI может быть окном, как показано в следующем примере.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="MainWindow.xaml" />
Автономные приложения и XAML-приложения браузера (XBAP) могут также указать страницу в качестве начального пользовательского интерфейса, как показано в следующем примере.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="HomePage.xaml" />
Если приложение — это автономное приложение, и в качестве StartupUri указана страница, WPF открывает NavigationWindow для размещения этой страницы. В случае XBAP, страница будет отображена в браузере основного приложения.
Переход на страницу
В следующем примере показано, как перейти на какую-либо страницу.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Page With Hyperlink"
WindowWidth="250"
WindowHeight="250">
<Hyperlink NavigateUri="UriOfPageToNavigateTo.xaml">
Navigate to Another Page
</Hyperlink>
</Page>
Дополнительные сведения о различных способах перехода в WPF см. в разделе Общие сведения о переходах.
Указание значка окна
В следующем примере показано использование URI для указания значка окна.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MainWindow"
Icon="WPFIcon1.ico">
</Window>
Дополнительные сведения см. в разделе Icon.
Загрузка файлов изображения, аудио и видео файлов
WPF позволяет приложениям использовать разнообразные типы носителей, все из которых можно определить и загрузить с помощью Pack URI, как показано в следующих примерах.
<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/bee.wmv" />
<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/ringin.wav" />
<Image Source="Images/Watermark.png" />
Дополнительные сведения о работе с мультимедийным содержимым см. в разделе графика и мультимедиа.
Загрузка словаря ресурсов с исходного узла
Словари ресурсов (ResourceDictionary) можно использовать для поддержки тем приложения. Одним из способов создания тем и управления ими является создание нескольких тем в качестве словарей ресурсов, расположенных в исходном узле приложения. Это позволяет добавлять и обновлять темы без повторной компиляции и развертывания приложения. Словари ресурсов можно определить и загрузить с помощью Pack URI, как показано в следующем примере.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="HomePage.xaml">
<Application.Resources>
<ResourceDictionary Source="pack://siteoforigin:,,,/PageTheme.xaml" />
</Application.Resources>
</Application>
Обзор тем в WPF см. в разделе Стилизация и использование шаблонов.