Compartir a través de


Recursos, contenido y archivos de datos de la aplicación WPF

Las aplicaciones de Microsoft Windows suelen depender de archivos que contienen datos no ejecutables, como lenguaje de marcado extensible de aplicaciones (XAML), imágenes, vídeo y audio. Windows Presentation Foundation (WPF) ofrece compatibilidad especial para configurar, identificar y usar estos tipos de archivos de datos, que se denominan archivos de datos de la aplicación. Esta compatibilidad gira en torno a un conjunto específico de tipos de archivo de datos de aplicación, entre los que se incluyen:

  • Archivos de recursos: archivos de datos que se compilan en un ensamblado de WPF ejecutable o biblioteca.

  • Archivos de contenido: archivos de datos independientes que tienen una asociación explícita con un ensamblado WPF ejecutable.

  • Sitio de archivos de origen: archivos de datos independientes que no tienen ninguna asociación con un ensamblado WPF ejecutable.

Una distinción importante que se debe hacer entre estos tres tipos de archivos es que los archivos de recursos y los archivos de contenido se conocen en tiempo de compilación; un ensamblado tiene conocimientos explícitos de ellos. Sin embargo, en el caso de los archivos de sitio de origen, un ensamblado puede no tener conocimiento de ellos en absoluto o de conocimientos implícitos a través de una referencia de identificador uniforme de recursos (URI) del paquete; el caso de este último, no hay ninguna garantía de que el sitio de origen al que se hace referencia existe realmente.

Para hacer referencia a los archivos de datos de la aplicación, Windows Presentation Foundation (WPF) usa el esquema de identificador uniforme de recursos (URI) del paquete, que se describe detalladamente en URI del paquete en WPF).

En este tema se describe cómo configurar y usar archivos de datos de aplicación.

Archivos de recursos

Si un archivo de datos de aplicación siempre debe estar disponible para una aplicación, la única manera de garantizar la disponibilidad es compilarlo en el ensamblado ejecutable principal de una aplicación o en uno de sus ensamblados a los que se hace referencia. Este tipo de archivo de datos de aplicación se conoce como un archivo de recursos.

Debe usar archivos de recursos cuando:

  • No es necesario actualizar el contenido del archivo de recursos después de compilarlo en un ensamblado.

  • Quiere simplificar la complejidad de la distribución de aplicaciones al reducir el número de dependencias de archivo.

  • El archivo de datos de la aplicación debe ser localizable (consulte Información general sobre la globalización y la localización de WPF).

Nota:

Los archivos de recursos descritos en esta sección son diferentes de los archivos de recursos descritos en Recursos XAML y distintos de los recursos incrustados o vinculados descritos en Administrar recursos de aplicación (.NET).

Configuración de archivos de recursos

En WPF, un archivo de recursos es un archivo que se incluye en un proyecto del motor de compilación de Microsoft (MSBuild) como elemento Resource .

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <ItemGroup>
    <Resource Include="ResourceFile.xaml" />
  </ItemGroup>
  ...
</Project>

Nota:

En Visual Studio, se crea un archivo de recursos al agregar un archivo a un proyecto y ajustando su Build Action a Resource.

Cuando se compila el proyecto, MSBuild compila el recurso en el ensamblado.

Uso de archivos de recursos

Para cargar un archivo de recursos, puede llamar al GetResourceStream método de la Application clase , pasando un URI de paquete que identifica el archivo de recursos deseado. GetResourceStream devuelve un StreamResourceInfo objeto , que expone el archivo de recursos como Stream y describe su tipo de contenido.

Por ejemplo, el código siguiente muestra cómo usar GetResourceStream para cargar un Page archivo de recursos y establecerlo como el contenido de un Frame elemento (pageFrame):

// Navigate to xaml page
Uri uri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetResourceStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
' Navigate to xaml page
Dim uri As New Uri("/PageResourceFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetResourceStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page

Al llamar a GetResourceStream, se obtiene acceso a Stream, pero es necesario realizar el trabajo adicional de convertirlo al tipo de la propiedad como la que se establecerá. En su lugar, puede permitir que WPF se ocupe de abrir y convertir el Stream al cargar un archivo de recursos directamente en la propiedad de un tipo mediante código.

En el ejemplo siguiente se muestra cómo cargar un elemento Page directamente en un Frame (pageFrame) mediante código.

Uri pageUri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
Dim pageUri As New Uri("/PageResourceFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri

El ejemplo siguiente es el equivalente de marcado del ejemplo anterior.

<Frame Name="pageFrame" Source="PageResourceFile.xaml" />

Archivos de código de aplicación como archivos de recursos

Se puede hacer referencia a un conjunto especial de archivos de código de aplicación WPF mediante URI de paquete, como ventanas, páginas, documentos de flujo y diccionarios de recursos. Por ejemplo, puede establecer la Application.StartupUri propiedad con un URI de paquete que haga referencia a la ventana o página que desea cargar cuando se inicie una aplicación.

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

Puede hacerlo cuando se incluye un archivo XAML en un proyecto de MSBuild como elemento Page .

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <ItemGroup>
    <Page Include="MainWindow.xaml" />
  </ItemGroup>
  ...
</Project>

Nota:

En Visual Studio, cuando se agrega un nuevo Window, NavigationWindow, Page, FlowDocument o ResourceDictionary a un proyecto, el valor predeterminado para el archivo de marcado será Build Action.

Cuando se compila un proyecto con Page elementos, los elementos XAML se convierten en formato binario y se compilan en el ensamblado asociado. Por lo tanto, estos archivos se pueden usar de la misma manera que los archivos de recursos típicos.

Nota:

Si un archivo XAML está configurado como un Resource elemento y no tiene un archivo de código subyacente, el XAML sin formato se compila en un ensamblado en lugar de en una versión binaria del XAML sin formato.

Archivos de contenido

Un archivo de contenido se distribuye como un archivo flexible junto con un ensamblado ejecutable. Aunque no se compilan en un ensamblado, los ensamblados se compilan con metadatos que establecen una asociación con cada archivo de contenido.

Debe usar archivos de contenido cuando la aplicación requiera un conjunto específico de archivos de datos de aplicación que quiera poder actualizar sin volver a compilar el ensamblado que los consume.

Configuración de archivos de contenido

Para agregar un archivo de contenido a un proyecto, se debe incluir un archivo de datos de aplicación como elemento Content . Además, dado que un archivo de contenido no se compila directamente en el ensamblado, debe establecer el elemento de metadatos de MSBuild CopyToOutputDirectory para especificar que el archivo de contenido se copia en una ubicación relativa al ensamblado compilado. Si desea que el recurso se copie en la carpeta de salida de compilación cada vez que se compile un proyecto, establezca el elemento de metadatos CopyToOutputDirectory con el valor Always. De lo contrario, puede asegurarse de que solo se copie la versión más reciente del recurso a la carpeta de salida de la compilación utilizando el valor PreserveNewest.

A continuación se muestra un archivo configurado como un archivo de contenido que se copia en la carpeta de salida de compilación solo cuando se agrega una nueva versión del recurso al proyecto.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <ItemGroup>
    <Content Include="ContentFile.xaml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  ...
</Project>

Nota:

En Visual Studio, se crea un archivo de contenido agregando un archivo a un proyecto y estableciendo su Build Action a Content, y estableciendo su Copy to Output Directory a Copy always (igual que Always) y Copy if newer (igual que PreserveNewest).

Cuando se compila el proyecto, se compila un AssemblyAssociatedContentFileAttribute atributo en los metadatos del ensamblado para cada archivo de contenido.

[assembly: AssemblyAssociatedContentFile("ContentFile.xaml")]

El valor de AssemblyAssociatedContentFileAttribute implica la ruta al archivo de contenido en relación con su posición en el proyecto. Por ejemplo, si un archivo de contenido se encontraba en una subcarpeta de proyecto, la información adicional de la ruta se incorporaría en el valor AssemblyAssociatedContentFileAttribute.

[assembly: AssemblyAssociatedContentFile("Resources/ContentFile.xaml")]

El AssemblyAssociatedContentFileAttribute valor también es el valor de la ruta de acceso al archivo de contenido en la carpeta de salida de compilación.

Uso de archivos de contenido

Para cargar un archivo de contenido, puede llamar al GetContentStream método de la Application clase , pasando un URI de paquete que identifica el archivo de contenido deseado. GetContentStream devuelve un StreamResourceInfo objeto , que expone el archivo de contenido como Stream y describe su tipo de contenido.

Por ejemplo, el código siguiente muestra cómo usar GetContentStream para cargar un Page archivo de contenido y establecerlo como el contenido de (FramepageFrame).

// Navigate to xaml page
Uri uri = new Uri("/PageContentFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
' Navigate to xaml page
Dim uri As New Uri("/PageContentFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetContentStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page

Al llamar a GetContentStream, se obtiene acceso a Stream, pero es necesario realizar el trabajo adicional de convertirlo al tipo de la propiedad como la que se establecerá. En su lugar, puede permitir que WPF se ocupe de abrir y convertir el Stream al cargar un archivo de recursos directamente en la propiedad de un tipo mediante código.

En el ejemplo siguiente se muestra cómo cargar un elemento Page directamente en un Frame (pageFrame) mediante código.

Uri pageUri = new Uri("/PageContentFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
Dim pageUri As New Uri("/PageContentFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri

El ejemplo siguiente es el equivalente de marcado del ejemplo anterior.

<Frame Name="pageFrame" Source="PageContentFile.xaml" />

Sitio de archivos de origen

Los archivos de recursos tienen una relación explícita con los ensamblados con los que se distribuyen, tal como se define por el AssemblyAssociatedContentFileAttribute. Sin embargo, hay ocasiones en las que es posible que desee establecer una relación implícita o inexistente entre un ensamblado y un archivo de datos de aplicación, incluido cuándo:

  • Un archivo no existe en tiempo de compilación.

  • No sabe qué archivos necesitará el ensamblado hasta el tiempo de ejecución.

  • Quieres poder actualizar archivos sin volver a compilar el ensamblado al que están asociados.

  • La aplicación usa archivos de datos de gran tamaño, como audio y vídeo, y solo quiere que los usuarios los descarguen si deciden hacerlo.

Es posible cargar estos tipos de archivos utilizando esquemas URI tradicionales, como los esquemas file:/// y http://.

<Image Source="file:///C:/DataFile.bmp" />
<Image Source="http://www.datafilewebsite.com/DataFile.bmp" />

Sin embargo, los file:/// y http:// esquemas requieren que tu aplicación tenga plena confianza. Si la aplicación es una aplicación de explorador XAML (XBAP) que se inició desde Internet o intranet, y solicita solo el conjunto de permisos que se permiten para las aplicaciones iniciadas desde esas ubicaciones, los archivos sueltos solo se pueden cargar desde el sitio de origen de la aplicación (ubicación de inicio). Estos archivos se conocen como archivos de sitio de origen .

Los archivos de sitio de origen son la única opción para las aplicaciones de confianza parcial, aunque no se limitan a las aplicaciones de confianza parcial. Es posible que las aplicaciones de plena confianza todavía necesiten cargar archivos de datos de aplicación que no conozcan en tiempo de compilación; aunque las aplicaciones de plena confianza podrían usar file:///, es probable que los archivos de datos de la aplicación se instalen en la misma carpeta que, o una subcarpeta del ensamblado de la aplicación. En este caso, el uso del sitio de referencia de origen es más fácil que usar file:///, ya que el uso de file:/// requiere que se realice la ruta de acceso completa al archivo.

Nota:

Los archivos de sitio de origen no se almacenan en caché con una aplicación de explorador XAML (XBAP) en un equipo cliente, mientras que los archivos de contenido sí se almacenan en caché. Por lo tanto, solo se descargan cuando se solicitan específicamente. Si una aplicación de explorador XAML (XBAP) tiene archivos multimedia grandes, configurarlos como sitio de archivos de origen significa que el inicio de la aplicación inicial es mucho más rápido y los archivos solo se descargan a petición.

Configuración de archivos de sitio de origen

Si los archivos de origen de su sitio no existen o son desconocidos en tiempo de compilación, debe usar mecanismos de implementación tradicionales para asegurarse de que los archivos necesarios estén disponibles en tiempo de ejecución, incluyendo el uso del programa de línea de comandos XCopy o del instalador de Microsoft Windows.

Si conoce en tiempo de compilación los archivos que desea ubicar en el sitio de origen, pero desea evitar una dependencia explícita, puede agregar esos archivos a un proyecto de MSBuild como None elemento. Al igual que con los archivos de contenido, debe establecer el atributo MSBuild CopyToOutputDirectory para especificar que el archivo en el sitio de origen se copia en una ubicación acorde al ensamblado compilado, especificando el valor de Always o PreserveNewest.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <None Include="PageSiteOfOriginFile.xaml">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
  ...
</Project>

Nota:

En Visual Studio, puedes crear un archivo de origen del sitio agregando un archivo a un proyecto y configurando sus propiedades de Build Action a None.

Cuando se compila el proyecto, MSBuild copia los archivos especificados en la carpeta de salida de compilación.

Uso de archivos del sitio de origen

Para cargar un archivo de sitio de origen, puede llamar al GetRemoteStream método de la Application clase , pasando un URI de paquete que identifica el sitio de origen deseado. GetRemoteStream devuelve un StreamResourceInfo objeto , que expone el sitio del archivo de origen como Stream y describe su tipo de contenido.

Por ejemplo, el siguiente código muestra cómo usar GetRemoteStream para cargar un archivo de origen del sitio Page y establecerlo como el contenido de un Frame (pageFrame).

// Navigate to xaml page
Uri uri = new Uri("/SiteOfOriginFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetRemoteStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
' Navigate to xaml page
Dim uri As New Uri("/SiteOfOriginFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetRemoteStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page

Al llamar a GetRemoteStream, se obtiene acceso a Stream, pero es necesario realizar el trabajo adicional de convertirlo al tipo de la propiedad como la que se establecerá. En su lugar, puede permitir que WPF se ocupe de abrir y convertir el Stream al cargar un archivo de recursos directamente en la propiedad de un tipo mediante código.

En el ejemplo siguiente se muestra cómo cargar un elemento Page directamente en un Frame (pageFrame) mediante código.

Uri pageUri = new Uri("pack://siteoforigin:,,,/SiteOfOriginFile.xaml", UriKind.Absolute);
this.pageFrame.Source = pageUri;
Dim pageUri As New Uri("pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml", UriKind.Absolute)
Me.pageFrame.Source = pageUri

El ejemplo siguiente es el equivalente de marcado del ejemplo anterior.

<Frame Name="pageFrame" Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />

Volver a generar después de cambiar el tipo de compilación

Después de cambiar el tipo de compilación de un archivo de datos de aplicación, debe recompilar toda la aplicación para asegurarse de que se aplican esos cambios. Si solo compila la aplicación, no se aplican los cambios.

Consulte también