Поделиться через


Пакетные URI в WPF

В Windows Presentation Foundation (WPF) универсальные идентификаторы ресурсов (URI) используются для идентификации и загрузки файлов различными способами, включая следующие:

  • Указание пользовательского интерфейса для отображения при первом запуске приложения.

  • Загрузка изображений.

  • Переход на страницы.

  • Загрузка файлов данных, не являющихся исполняемыми.

Кроме того, URI можно использовать для идентификации и загрузки файлов из различных расположений, включая следующие:

  • Текущая сборка.

  • Ссылаемая сборка.

  • Расположение относительно сборки.

  • Сайт источника приложения.

Чтобы обеспечить согласованный механизм идентификации и загрузки этих типов файлов из этих расположений, WPF использует расширяемость схемы URI пакета. В этом разделе представлен обзор схемы, в которой рассматриваются способы создания URI пакетов для различных сценариев, рассматриваются абсолютные и относительные URI и разрешение URI, прежде чем показано, как использовать URI пакетов из разметки и кода.

Схема URI пакета

Схема URI пакета используется спецификацией Open Packaging Conventions (OPC), которая описывает модель для организации и идентификации содержимого. Ключевыми элементами этой модели являются пакеты и части, где пакет является логическим контейнером для одной или нескольких логических частей. На следующем рисунке показана эта концепция.

Схема пакетов и частей

Чтобы определить части, спецификация OPC использует расширяемость RFC 2396 (универсальные идентификаторы ресурсов (URI): универсальный синтаксис) для определения схемы URI пакета.

Схема, указанная URI, определяется его префиксом; Примерами являются http, ftp и file. Схема URI пакета использует "pack" как свою схему и содержит два компонента: авторизация и путь. Ниже приведен формат URI пакета.

pack://authority/Путь

Орган указывает тип пакета, в который заключен элемент, в то время как путь указывает расположение элемента в пакете.

Эта концепция показана на следующем рисунке:

Связь между пакетом, авторитетом и путем

Пакеты и части аналогичны приложениям и файлам, где приложение (пакет) может включать один или несколько файлов (частей), в том числе:

  • Файлы ресурсов, скомпилированные в локальную сборку.

  • Файлы ресурсов, скомпилированные в сборку, на которую ссылаются.

  • Файлы ресурсов, скомпилированные в сборку, на которую есть ссылка.

  • Файлы контента.

  • Сайт оригинальных файлов.

Для доступа к этим типам файлов WPF поддерживает два протокола: application:/// и siteoforigin:///. Центр application:/// определяет файлы данных приложения, известные во время компиляции, включая файлы ресурсов и содержимого. Центр siteoforigin:/// определяет сайт файлов источника. Сфера полномочий каждого органа показана на следующем рисунке.

Схема URI пакета

Замечание

Компонент авторитета пакета URI — это встроенный URI, который указывает на пакет и должен соответствовать RFC 2396. Кроме того, символ "/" должен быть заменен на символ ",", а такие зарезервированные символы, как "%" и "?", должны быть экранированы. Дополнительные сведения см. в OPC.

В следующих разделах объясняется, как создавать URI пакетов с использованием этих двух полномочий в сочетании с соответствующими путями для идентификации ресурсов, содержания и файлов источника происхождения.

URI пакета файлов ресурсов

Файлы ресурсов настраиваются как элементы MSBuild Resource и компилируются в сборки. WPF поддерживает создание URI пакетов, которые можно использовать для идентификации файлов ресурсов, скомпилированных в локальную сборку или скомпилированных в сборку, на которую ссылается локальная сборка.

Файл ресурса локальной сборки

URI пакета ресурсного файла, скомпилированного в локальную сборку, использует следующий авторитет и путь.

  • Уполномоченный орган: application:///.

  • Путь: имя файла ресурса, включая его путь, относительно корневого каталога локальной папки проекта сборки.

В следующем примере показан URI пакета для файла ресурсов XAML, расположенного в корне папки проекта локальной сборки.

pack://application:,,,/ResourceFile.xaml

В следующем примере показан URI пакета для файла ресурсов XAML, расположенного в подпапке папки проекта локальной сборки.

pack://application:,,,/Subfolder/ResourceFile.xaml

Файл ресурса сборки, на который делается ссылка

URI пакета для файла ресурсов, скомпилированного в ссылаемую сборку, использует следующие полномочия и путь:

  • Уполномоченный орган: application:///.

  • Путь: Имя файла ресурса, скомпилированного в сборку, к которой производится ссылка. Путь должен соответствовать следующему формату:

    AssemblyShortName{; Версия]{; ОткрытыйКлюч]; компонент/Путь

    • AssemblyShortName: короткое имя для указанной сборки.

    • ; Версия [необязательно]: версия указанной сборки, содержащей файл ресурса. Используется при загрузке двух или более ссылочных сборок с одинаковым коротким именем.

    • ; PublicKey [необязательно]: открытый ключ, используемый для подписи указанной сборки. Используется при загрузке двух или более ссылочных сборок с одинаковым коротким именем.

    • ; компонент: указывает, что сборка, на которую ссылаются, взята из локальной сборки.

    • /Path: имя файла ресурса, включая его путь, относительно корневого каталога проекта указанной сборки.

В следующем примере показан URI пакета для файла ресурсов XAML, расположенного в корневой папке проекта указанной сборки.

pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml

В следующем примере показан URI пакета для файла ресурсов XAML, расположенного в подпапке папки проекта, на которую ссылается сборка.

pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

В следующем примере показан URI пакета для файла ресурсов XAML, расположенного в корневой папке указанной версии папки проекта конкретной сборки.

pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml

Обратите внимание, что синтаксис URI пакета для ссылочных файлов ресурсов сборки можно использовать только с авторитетом application:///. Например, в WPF не поддерживается следующее.

pack://siteoforigin:,,,/SomeAssembly;component/ResourceFile.xaml

URI пакета файлов содержимого

URI пакета для файла содержимого использует следующий авторитет и путь:

  • Уполномоченный орган: application:///.

  • Путь: имя файла содержимого, включая путь относительно расположения файловой системы основной исполняемой сборки приложения.

В следующем примере показан URI пакета для файла содержимого XAML, расположенного в той же папке, что и исполняемая сборка.

pack://application:,,,/ContentFile.xaml

В следующем примере показан URI пакета для файла содержимого XAML, расположенного в подпапке относительно исполняемой сборки приложения.

pack://application:,,,/Subfolder/ContentFile.xaml

Замечание

Не удается перейти к HTML-файлам содержимого. Схема URI поддерживает только навигацию по HTML-файлам, расположенным на сайте источника.

URI для пакетов с местом происхождения

URI пакета для исходного файла использует следующий авторитет и путь:

  • Орган: siteoforigin:///.

  • Путь: имя файла исходного сайта, включая путь относительно места запуска исполняемой сборки.

Следующий пример демонстрирует URI пакета для XAML-файла отправной точки, который хранится в папке, из которой запускается исполняемая сборка.

pack://siteoforigin:,,,/SiteOfOriginFile.xaml

В следующем примере показан универсальный код ресурса (URI) пакета для исходного файла XAML, хранящийся в вложенной папке относительно расположения, из которого запускается исполняемая сборка приложения.

pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml

Файлы страниц

XAML-файлы, настроенные как элементы MSBuild Page , компилируются в сборки так же, как и файлы ресурсов. Следовательно, элементы MSBuild Page можно определить с помощью URI пакетов для файлов ресурсов.

Типы ФАЙЛОВ XAML, которые обычно настраиваются как элементы MSBuildPage , имеют один из следующих элементов в качестве корневого элемента:

Абсолютные и относительные URI пакета

Полный унифицированный указатель ресурса (URI) пакета включает схему, авторитет и путь и считается абсолютным унифицированным указателем ресурса (URI) пакета. В целях упрощения для разработчиков элементы XAML обычно позволяют задавать соответствующие атрибуты, используя относительный URI пакета, который включает только путь.

Например, рассмотрим следующий абсолютный URI пакета для файла ресурсов в локальной сборке.

pack://application:,,,/ResourceFile.xaml

Относительный URI пакета, ссылающийся на этот файл ресурсов, будет следующим.

/ResourceFile.xaml

Замечание

Так как файлы источника не связаны с сборками, они могут ссылаться только на абсолютные URI пакетов.

По умолчанию относительный URI пакета интерпретируется относительно местоположения разметки или кода, который содержит ссылку. Если обратная косая черта используется в начале, ссылка на относительный URI пакета рассматривается как относительная по отношению к корневой части приложения. Например, рассмотрим следующую структуру проекта.

App.xaml

Page2.xaml

\SubFolder

+ Page1.xaml

+ Page2.xaml

Если Page1.xaml содержит URI, ссылающийся на Root\SubFolder\Page2.xaml, ссылка может использовать следующий относительный URI пакета.

Page2.xaml

Если Page1.xaml содержит URI, ссылающийся на Root\Page2.xaml, ссылка может использовать следующий относительный URI пакета.

/Page2.xaml

Разрешение URI пакета

Формат URI пакетов позволяет использовать URI пакетов для разных типов файлов, которые будут выглядеть одинаково. Например, рассмотрим следующий абсолютный URI пакета.

pack://application:,,,/ResourceOrContentFile.xaml

Этот абсолютный универсальный код ресурса (URI) пакета может ссылаться на файл ресурсов в локальной сборке или файл содержимого. То же самое верно для следующего относительного URI.

/ResourceOrContentFile.xaml

Чтобы определить тип файла, на который ссылается URI пакета, WPF определяет URI для файлов ресурсов в локальных сборках и содержательных файлах, используя эвристический подход.

  1. Проверка метаданных сборки для атрибута AssemblyAssociatedContentFileAttribute , соответствующего URI пакета.

  2. AssemblyAssociatedContentFileAttribute Если атрибут найден, путь URI пакета ссылается на файл содержимого.

  3. Если атрибут AssemblyAssociatedContentFileAttribute не найден, проверьте файлы ресурсов набора, скомпилированные в локальную сборку.

  4. Если найден файл ресурса, совпадающий с путем URI пакета, путь URI пакета ссылается на файл ресурса.

  5. Если ресурс не найден, внутренне созданный объект Uri недействителен.

Разрешение URI не применяется для ссылок на следующие:

  • Файлы содержимого в ссылочных сборках: эти типы файлов не поддерживаются WPF.

  • Внедренные файлы в ссылочных сборках: URI, которые идентифицируют их, являются уникальными, так как они включают имя указанной сборки и ;component суффикс.

  • Сайт исходного файла: URI, которые идентифицируют их, являются уникальными, так как они являются единственными файлами, которые можно определить по URI пакета, которые содержат центр siteoforigin:///.

Одно упрощение разрешения URI пакета позволяет коду быть несколько независимо от расположений файлов ресурсов и содержимого. Например, если у вас есть файл ресурса в локальной сборке, который перенастроен на файл содержимого, URI ресурса остается прежним, как и код, который использует этот пак URI.

Программирование с помощью URI пакетов

Многие классы WPF реализуют свойства, которые можно задать с помощью URI пакета, в том числе:

Эти свойства можно задать как из разметки, так и из кода. В этом разделе показаны основные конструкции для обоих, а затем показаны примеры распространенных сценариев.

Использование URI пакетов в разметке

URI пакета указывается в разметке путем установки атрибута с этим URI. Рассмотрим пример.

<element attribute="pack://application:,,,/File.xaml" />

В таблице 1 показаны различные абсолютные URI пакетов, которые можно указать в разметке.

Таблица 1. Абсолютные URI пакетов в разметке

Файл Абсолютный 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 показаны различные относительные URI пакетов, которые можно указать в разметке.

Таблица 2. Относительные URI пакетов в разметке

Файл Относительный URI пакета
Файл ресурсов в локальной сборке "/ResourceFile.xaml"
Файл ресурсов в вложенной папке локальной сборки "/Subfolder/ResourceFile.xaml"
Файл ресурсов в указанной сборке "/ReferencedAssembly;component/ResourceFile.xaml"
Файл ресурсов в подпапке сборки, на которую есть ссылка "/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
Файл содержимого "/ContentFile.xaml"
Файл содержимого в вложенной папке "/Subfolder/ContentFile.xaml"

Использование URI пакетов в коде

URI пакета в коде можно указать путем создания экземпляра Uri класса и передачи URI пакета в качестве параметра конструктору. Это показано в следующем примере.

Uri uri = new Uri("pack://application:,,,/File.xaml");

По умолчанию Uri класс считает URI пакетов абсолютным. Следовательно, исключение возникает при создании экземпляра класса Uri с относительным пакетным 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 если вы уверены, что указанный URI пакета является одним или другим. Если вы не знаете тип используемого URI пакета, например когда пользователь вводит универсальный код ресурса (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 показаны различные относительные URI пакетов, которые можно указать в коде с помощью System.Uri.

Таблица 3. Абсолютные URI пакетов в коде

Файл Абсолютный 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 показаны различные относительные URI пакетов, которые можно указать в коде с помощью System.Uri.

Таблица 4. Относительные URI пакетов в коде

Файл Относительный 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 пакета

В предыдущих разделах описано, как создавать URI пакетов для идентификации ресурсов, содержимого и сайта файлов источника. В WPF эти конструкции используются различными способами, и в следующих разделах рассматриваются несколько распространенных вариантов использования.

Указание пользовательского интерфейса для отображения при запуске приложения

StartupUri указывает первый пользовательский интерфейс для отображения при запуске приложения WPF. Для автономных приложений пользовательский интерфейс может быть окном, как показано в следующем примере.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

Автономные приложения и приложения браузера XAML (XBAPs) также могут указывать страницу в качестве исходного пользовательского интерфейса, как показано в следующем примере.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

Если приложение является автономным приложением и страница указана с помощью StartupUri, WPF откроет NavigationWindow для размещения страницы. Для XBAPs страница отображается в браузере узла.

В следующем примере показано, как перейти на страницу.

<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 позволяет приложениям использовать широкий спектр типов носителей, все из которых можно определить и загрузить с помощью 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) можно использовать для поддержки тем приложений. Одним из способов создания тем и управления ими является создание нескольких тем в виде словарей ресурсов, расположенных на сайте источника приложения. Это позволяет добавлять и обновлять темы без повторной компиляции и повторного развертывания приложения. Эти словари ресурсов можно определить и загрузить с помощью 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 см. в разделе "Стилизация" и "Шаблон".

См. также