Empaquetar URI en WPF

En Windows Presentation Foundation (WPF), se utilizan uniform resource identifiers (URIs) para identificar y cargar archivos de muchas maneras, incluidas las que figuran a continuación:

  • Especificando la user interface (UI) que se va a mostrar cuando se inicie una aplicación por primera vez.

  • Cargando imágenes.

  • Navegando a páginas.

  • Cargando archivos de datos no ejecutables.

Además, se pueden usar URIs para identificar y cargar archivos desde diversas ubicaciones, como las que figuran a continuación:

  • El ensamblado actual.

  • Un ensamblado al que se hace referencia.

  • Una ubicación relativa a un ensamblado.

  • El sitio de origen de la aplicación.

Para proporcionar un mecanismo coherente para identificar y cargar estos tipos de archivo desde estas ubicaciones, WPF aprovecha la extensibilidad del esquema de pack URI. En este tema se proporciona información general sobre el esquema, se describe cómo construir pack URIs para diversos escenarios, se explican los URIs absolutos y relativos y la resolución de URI antes de mostrar cómo utilizar los pack URIs tanto desde el marcado como desde el código.

Este tema contiene las secciones siguientes.

  • Esquema de pack URI
  • Pack URI de archivos de recursos
  • Pack URI de archivo de contenido
  • Pack URI de sitio de origen
  • Archivos de paginación
  • Pack URI absolutosy relativos
  • Resolución de pack URI
  • Programar con pack URI
  • Temas relacionados

Esquema de pack URI

El esquema de pack URI se utiliza en la especificación de Open Packaging Conventions (OPC), que describe un modelo para organizar e identificar contenido. Los elementos clave de este modelo son los paquetes y las partes, donde un paquete es un contenedor lógico para una o varias partes lógicas. La figura siguiente ilustra este concepto.

Diagrama de paquete y partes

Para identificar las partes, la especificación de OPC aprovecha la extensibilidad de RFC 2396 (Identificadores uniformes de recursos (URI): sintaxis genérica) para definir el esquema de pack URI.

El esquema especificado por un URI se define por su prefijo; http, ftp y file son ejemplos conocidos. El esquema de pack URI utiliza "pack" como esquema y tiene dos componentes: la autoridad y la ruta de acceso. A continuación figura el formato de un pack URI.

pack://autoridad/ruta de acceso

La autoridad especifica el tipo de paquete que contiene una parte, mientras que la ruta de acceso especifica la ubicación de una parte dentro de un paquete.

Este concepto se ilustra en la siguiente figura:

Relación entre paquete, autoridad y ruta de acceso

Los paquetes y las partes son análogos a las aplicaciones y los archivos, puesto que una aplicación (paquete) puede incluir uno o varios archivos (partes), como los siguientes:

  • Archivos de recursos que se compilan en el ensamblado local.

  • Archivos de recursos que se compilan en un ensamblado al que se hace referencia.

  • Archivos de recursos que se compilan en un ensamblado que hace referencia.

  • Archivos de contenido.

  • Archivos de sitio de origen.

Para obtener acceso a estos tipos de archivo, WPF admite dos autoridades: application:/// y siteoforigin:///. La autoridad application:/// identifica los archivos de datos de aplicación que se conocen en tiempo de compilación, incluidos los archivos de recursos y de contenido. La autoridad siteoforigin:/// identifica los archivos de sitio de origen. El ámbito de cada autoridad se muestra en la figura siguiente.

Diagrama de URI de paquete

NotaNota

El componente de autoridad de un pack URI es un URI incrustado que apunta a un paquete y debe ajustarse a RFC 2396.Además, el carácter "/" debe sustituirse por el carácter "," y los caracteres reservados tales como "%" y "?" deben incluirse en secuencias de escape.Vea la especificación de OPC para obtener información detallada.

En las secciones siguientes se explica cómo construir pack URIs utilizando estas dos autoridades junto con las rutas de acceso adecuadas para identificar los archivos de recursos, de contenido y de sitio de origen.

Pack URI de archivos de recursos

Los archivos de recursos se configuran como elementos MSBuildResource y se compilan en ensamblados. WPF admite la construcción de pack URIs que se pueden utilizar para identificar los archivos de recursos compilados en el ensamblado local o compilados en un ensamblado al que se hace referencia desde el ensamblado local.

Archivo de recursos del ensamblado local

El pack URI para un archivo de recursos compilado en el ensamblado local utiliza la siguiente autoridad y ruta de acceso:

  • Autoridad: application:///.

  • Ruta de acceso: nombre del archivo de recursos, incluida su ruta de acceso relativa a la carpeta raíz del proyecto de ensamblado local.

En el ejemplo siguiente se muestra el pack URI para un archivo de recursos XAML que se encuentra en la carpeta raíz del proyecto de ensamblado local.

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

En el ejemplo siguiente se muestra el pack URI para un archivo de recursos XAML que se encuentra en una subcarpeta de la carpeta del proyecto de ensamblado local.

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

Archivo de recursos del ensamblado al que se hace referencia

El pack URI para un archivo de recursos compilado en un ensamblado al que se hace referencia utiliza la siguiente autoridad y ruta de acceso:

  • Autoridad: application:///.

  • Ruta de acceso: nombre de un archivo de recursos compilado en un ensamblado al que se hace referencia. La ruta de acceso debe tener el formato siguiente:

    nombreCortoDeEnsamblado[;Versión][;clavePública];component/rutaDeAcceso

    • nombreCortoDeEnsamblado: nombre corto del ensamblado al que se hace referencia.

    • ;Versión [opcional]: versión del ensamblado al que se hace referencia y que contiene el archivo de recursos. Se utiliza cuando hay cargados dos o más ensamblados a los que se hace referencia con el mismo nombre corto.

    • ;clavePública [opcional]: clave pública utilizada para firmar el ensamblado al que se hace referencia. Se utiliza cuando hay cargados dos o más ensamblados a los que se hace referencia con el mismo nombre corto.

    • ;component: especifica que la referencia al ensamblado se hace desde el ensamblado local.

    • /rutaDeAcceso: nombre del archivo de recursos, incluida su ruta de acceso relativa a la carpeta raíz del proyecto del ensamblado al que se hace referencia.

En el ejemplo siguiente se muestra el pack URI para un archivo de recursos XAML que se encuentra en la carpeta raíz del proyecto de ensamblado al que se hace referencia.

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

En el ejemplo siguiente se muestra el pack URI para un archivo de recursos XAML que se encuentra en una subcarpeta de la carpeta del proyecto de ensamblado al que se hace referencia.

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

En el ejemplo siguiente se muestra el pack URI para un archivo de recursos XAML que se encuentra en la carpeta raíz de un proyecto de ensamblado específico de la versión al que se hace referencia.

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

Observe que la sintaxis del pack URI para los archivos de recursos de ensamblado a los que se hace referencia solamente se puede utilizar con la autoridad application:///. Por ejemplo, no se admite lo siguiente en WPF.

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

Pack URI de archivo de contenido

El pack URI para un archivo de contenido utiliza la siguiente autoridad y ruta de acceso:

  • Autoridad: application:///.

  • Ruta de acceso: nombre del archivo de contenido, incluida su ruta de acceso relativa a la ubicación del sistema de archivos del ensamblado ejecutable principal de la aplicación.

En el ejemplo siguiente se muestra el pack URI para un archivo de contenido XAML, ubicado en la misma carpeta que el ensamblado ejecutable.

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

En el ejemplo siguiente se muestra el pack URI para un archivo de contenido XAML, situado en una subcarpeta relativa al ensamblado ejecutable de la aplicación.

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

NotaNota

No se puede navegar a los archivos de contenido HTML.El esquema de URI solamente admite la navegación a archivos HTML ubicados en el sitio de origen.

Pack URI de sitio de origen

El pack URI para un archivo de sitio de origen utiliza la siguiente autoridad y ruta de acceso:

  • Autoridad: siteoforigin:///.

  • Ruta de acceso: nombre del archivo de sitio de origen, incluida su ruta de acceso relativa a la ubicación desde la que se inició el ensamblado ejecutable.

En el ejemplo siguiente se muestra el pack URI para un archivo de sitio de origen XAML, almacenado en la ubicación desde la que se inicia el ensamblado ejecutable.

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

En el ejemplo siguiente se muestra el pack URI para un archivo de sitio de origen XAML, almacenado en una subcarpeta relativa a la ubicación desde la que se inicia el ensamblado ejecutable de la aplicación.

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

Archivos de paginación

Los archivos XAML configurados como elementos Page de MSBuild se compilan en ensamblados del mismo modo que los archivos de recursos. Por consiguiente, los elementos Page de MSBuild se pueden identificar mediante los pack URIs para los archivos de recursos.

Los tipos de archivo XAML que se configuran habitualmente como elementos Page de MSBuild tienen uno de los siguientes elementos como elemento raíz:

Pack URI absolutosy relativos

Un pack URI completo incluye el esquema, la autoridad y la ruta de acceso, y se considera un pack URI absoluto. Como simplificación para los desarrolladores, los elementos XAML suelen permitir que se establezcan los atributos adecuados con un pack URI relativo, que incluye solamente la ruta de acceso.

Por ejemplo, considere el siguiente pack URI absoluto para un archivo de recursos en el ensamblado local.

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

El pack URI relativo que hace referencia a este recurso sería el siguiente.

/ResourceFile.xaml

NotaNota

Dado que los archivos de sitio de origen no están asociados a ensamblados, solamente se puede hacer referencia a ellos con pack URIs absolutos.

De forma predeterminada, un pack URI relativo se considera relativo a la ubicación del marcado o del código que contiene la referencia. Sin embargo, si se utiliza una barra diagonal inversa inicial, el pack URI relativo se considera relativo a la raíz de la aplicación. Por ejemplo, considere la estructura de proyecto siguiente.

App.xaml

Page2.xaml

\SubFolder

  + Page1.xaml

  + Page2.xaml

Si Page1.xaml contiene un URI que hace referencia a Raíz\SubFolder\Page2.xaml, la referencia puede utilizar el siguiente pack URI.

Page2.xaml

Si Page1.xaml contiene un URI que hace referencia a Raíz\Page2.xaml, la referencia puede utilizar el siguiente pack URI relativo.

/Page2.xaml

Resolución de pack URI

El formato de los pack URIs permite que los pack URIs para diferentes tipos de archivo tengan la misma apariencia. Por ejemplo, considere el siguiente pack URI absoluto.

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

Este pack URI absoluto podría hacer referencia a un archivo de recursos del ensamblado local o a un archivo de contenido. Lo mismo se aplica al siguiente URI relativo.

/ResourceOrContentFile.xaml

Para determinar el tipo de archivo al que hace referencia un pack URI, WPF resuelve los URIs para los archivos de recursos en ensamblados locales y los archivos de contenido usando la siguiente heurística:

  1. Sondear los metadatos del ensamblado para buscar un atributo AssemblyAssociatedContentFileAttribute que coincida con el pack URI.

  2. Si se encuentra el atributo AssemblyAssociatedContentFileAttribute, la ruta de acceso del pack URI hace referencia a un archivo de contenido.

  3. Si no se encuentra el atributo AssemblyAssociatedContentFileAttribute, sondee los archivos de recursos establecidos que están compilados en el ensamblado local.

  4. Si se encuentra un archivo de recursos que coincida con el pack URI, la ruta de acceso del pack URI hace referencia a un archivo de recursos.

  5. Si no se encuentra el recurso, el Uri creado internamente no es válido.

La resolución de URI no se aplica a los URIs que hacen referencia a los siguientes archivos:

  • Archivos de contenido en ensamblados a los que se hace referencia: WPF no admite estos tipos de archivo.

  • Archivos incrustados en ensamblados a los que se hace referencia: los URIs que los identifican son únicos porque incluyen tanto el nombre del ensamblado al que se hace referencia como el sufijo ;component.

  • Archivos de sitio de origen: los URIs que los identifican son únicos porque son los únicos archivos que se pueden identificar mediante pack URIs que contienen la autoridad siteoforigin:///.

Una simplificación que permite la resolución de pack URI es que el código sea independiente, hasta cierto punto, de la ubicación de los archivos de recursos y de contenido. Por ejemplo, si tiene un archivo de recursos en el ensamblado local que se ha reconfigurado para que sea un archivo de contenido, el pack URI para el recurso continuará siendo el mismo, al igual que el código que utiliza el pack URI.

Programar con pack URI

Muchas clases de WPF implementan propiedades que se pueden establecer con pack URIs, como:

Estas propiedades se pueden establecer tanto desde marcado como desde código. En esta sección se muestran las construcciones básicas para ambos y, a continuación, se muestra ejemplos de escenarios comunes.

Utilizar pack URI en el marcado

Un pack URI se especifica en el marcado estableciendo el elemento de un atributo con el pack URI. Por ejemplo:

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

En la tabla 1 se muestran los diversos pack URIs absolutos que se pueden especificar en el marcado.

Tabla 1: pack URI absolutos en el marcado

Archivo

Pack URI absoluto

Archivo de recursos: ensamblado local

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

Archivo de recursos en subcarpeta: ensamblado local

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

Archivo de recursos: ensamblado al que se hace referencia

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

Archivo de recursos en subcarpeta del ensamblado al que se hace referencia

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

Archivo de recursos en el ensamblado al que se hace referencia con versión

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

Archivo de contenido

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

Archivo de contenido en subcarpeta

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

Archivo de sitio de origen

"pack://siteoforigin:,,,/SOOFile.xaml"

Archivo de sitio de origen en subcarpeta

"pack://siteoforigin:,,,/Subfolder/SOOFile.xaml"

En la tabla 2 se muestran los diversos pack URIs relativos que se pueden especificar en el marcado.

Tabla 2: pack URI relativos en el marcado

Archivo

Pack URI relativo

Archivo de recursos en ensamblado local

"/ResourceFile.xaml"

Archivo de recursos en subcarpeta del ensamblado local

"/Subfolder/ResourceFile.xaml"

Archivo de recursos en ensamblado al que se hace referencia

"/ReferencedAssembly;component/ResourceFile.xaml"

Archivo de recursos en subcarpeta del ensamblado al que se hace referencia

"/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"

Archivo de contenido

"/ContentFile.xaml"

Archivo de contenido en subcarpeta

"/Subfolder/ContentFile.xaml"

Utilizar pack URI en el código

Para especificar un pack URI en el código, puede crear una instancia de la clase Uri y pasar el pack URI como parámetro al constructor. Esto último se muestra en el ejemplo siguiente.

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

De forma predeterminada, la clase Uri considera que el pack URIs es absoluto. Por consiguiente, se produce una excepción cuando se crea una instancia de la clase Uri con un pack URI relativo.

Uri uri = new Uri("/File.xaml");

Afortunadamente, la sobrecarga Uri(String, UriKind) del constructor de clase Uri acepta un parámetro de tipo UriKind para permitir que se especifique si un pack URI es absoluto o relativo.

// Absolute URI (default)
Uri absoluteUri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute);
// Relative URI
Uri relativeUri = new Uri("/File.xaml", UriKind.Relative);

Solamente se debe especificar Absolute o Relative cuando se tiene la seguridad de que el pack URI proporcionado es uno u otro. Si no conoce el tipo de pack URI que se utiliza, como cuando un usuario escribe un pack URI en tiempo de ejecución, utilice RelativeOrAbsolute.

// Relative or Absolute URI provided by user via a text box
TextBox userProvidedUriTextBox = new TextBox();
Uri uri = new Uri(userProvidedUriTextBox.Text, UriKind.RelativeOrAbsolute);

En la tabla 3 se muestran los diversos pack URIs relativos que se pueden especificar en el código utilizando System.Uri.

Tabla 3: pack URI absolutos en el código

Archivo

Pack URI absoluto

Archivo de recursos: ensamblado local

Uri uri = new Uri("pack://application:,,,/ResourceFile.xaml", UriKind.Absolute);

Archivo de recursos en subcarpeta: ensamblado local

Uri uri = new Uri("pack://application:,,,/Subfolder/ResourceFile.xaml", UriKind.Absolute);

Archivo de recursos: ensamblado al que se hace referencia

Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Absolute);

Archivo de recursos en subcarpeta del ensamblado al que se hace referencia

Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Absolute);

Archivo de recursos en el ensamblado al que se hace referencia con versión

Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml", UriKind.Absolute);

Archivo de contenido

Uri uri = new Uri("pack://application:,,,/ContentFile.xaml", UriKind.Absolute);

Archivo de contenido en subcarpeta

Uri uri = new Uri("pack://application:,,,/Subfolder/ContentFile.xaml", UriKind.Absolute);

Archivo de sitio de origen

Uri uri = new Uri("pack://siteoforigin:,,,/SOOFile.xaml", UriKind.Absolute);

Archivo de sitio de origen en subcarpeta

Uri uri = new Uri("pack://siteoforigin:,,,/Subfolder/SOOFile.xaml", UriKind.Absolute);

En la tabla 4 se muestran los diversos pack URIs relativos que se pueden especificar en el código utilizando System.Uri.

Tabla 4: pack URI relativos en el código

Archivo

Pack URI relativo

Archivo de recursos: ensamblado local

Uri uri = new Uri("/ResourceFile.xaml", UriKind.Relative);

Archivo de recursos en subcarpeta: ensamblado local

Uri uri = new Uri("/Subfolder/ResourceFile.xaml", UriKind.Relative);

Archivo de recursos: ensamblado al que se hace referencia

Uri uri = new Uri("/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Relative);

Archivo de recursos en subcarpeta: ensamblado al que se hace referencia

Uri uri = new Uri("/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Relative);

Archivo de contenido

Uri uri = new Uri("/ContentFile.xaml", UriKind.Relative);

Archivo de contenido en subcarpeta

Uri uri = new Uri("/Subfolder/ContentFile.xaml", UriKind.Relative);

Escenarios comunes de pack URI

En las secciones anteriores se ha explicado cómo construir pack URIs para identificar archivos de recursos, de contenido y de sitio de origen. En WPF, estas construcciones se utilizan de diversas maneras. En las secciones siguientes, se abordan varios usos comunes.

Especificar la interfaz de usuario que se va a mostrar cuando se inicie una aplicación

StartupUri especifica la primera UI que se va a mostrar cuando se inicie una aplicación WPF. En el caso de las aplicaciones independientes, la UI puede ser una ventana, como se muestra en el ejemplo siguiente.

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

Las aplicaciones independientes y las XAML browser applications (XBAPs) también pueden especificar una página como interfaz de usuario inicial, tal como se muestra en el ejemplo siguiente.

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

Si la aplicación es una aplicación independiente y hay una página especificada con StartupUri, WPF abre un objeto NavigationWindow para hospedar la página. En el caso de las XBAPs, la página se muestra en el explorador del host.

En el ejemplo siguiente se muestra cómo navegar a una página.

<Page
  xmlns="https://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>

Para obtener más información sobre las diversas maneras de navegar en WPF, vea Información general sobre navegación.

Especificar un icono de ventana

En el ejemplo siguiente se muestra cómo utilizar un URI para especificar el icono de una ventana.

<Window
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.MainWindow"
    Icon="WPFIcon1.ico">
</Window>

Para obtener más información, vea Icon.

Cargar archivos de imagen, audio y vídeo

WPF permite a las aplicaciones utilizar una amplia variedad de tipos multimedia, que se pueden identificar y cargar todos con pack URIs, tal como se muestra en los ejemplos siguientes.

<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" />

Para obtener más información sobre cómo trabajar con contenido multimedia, vea Gráficos y multimedia.

Cargar un diccionario de recursos desde el sitio de origen

Los diccionarios de recursos (ResourceDictionary) se pueden utilizar para ofrecer compatibilidad con los temas de aplicación. Una manera de crear y administrar temas consiste en crear varios temas como diccionarios de recursos que se encuentran en el sitio de origen de una aplicación. Esto permite agregar temas y actualizarlos sin tener que volver a compilar e implementar una aplicación. Estos diccionarios de recursos se pueden identificar y cargar mediante pack URIs, tal como se muestra en el ejemplo siguiente.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml">
  <Application.Resources>
    <ResourceDictionary Source="pack://siteoforigin:,,,/PageTheme.xaml" />
  </Application.Resources>
</Application>

Para obtener información general sobre los temas en WPF, vea Aplicar estilos y plantillas.

Vea también

Conceptos

Archivos de recursos, contenido y datos de aplicaciones de WPF