File di dati e di risorse dell'applicazione WPF

Le applicazioni Microsoft Windows spesso dipendono da file che contengono dati non eseguibili, ad esempio XAML (Extensible Application Markup Language), immagini, video e audio. Windows Presentation Foundation (WPF) offre un supporto speciale per la configurazione, l'identificazione e l'uso di questi tipi di file di dati, denominati file di dati dell'applicazione. Questo supporto si basa su un set specifico di tipi di file di dati dell'applicazione, che include:

  • File di risorse: file di dati compilati in un assembly WPF eseguibile o di libreria.

  • File di contenuto: file di dati autonomi che hanno un'associazione esplicita a un assembly WPF eseguibile.

  • File del sito di origine: file di dati autonomi che non hanno alcuna associazione con un assembly WPF eseguibile.

Un'importante distinzione da fare tra questi tre tipi di file riguarda il fatto che i file di risorse e i file di dati sono resi noti in fase di compilazione e pertanto sono conosciuti esplicitamente da un assembly. Per i file del sito di origine, tuttavia, un assembly potrebbe non conoscerli affatto o una conoscenza implicita tramite un riferimento URI (Uniform Resource Identifier) pack; il caso di quest'ultimo, non esiste alcuna garanzia che il sito di origine di riferimento esista effettivamente.

Per fare riferimento ai file di dati dell'applicazione, Windows Presentation Foundation (WPF) usa lo schema URI (Uniform Resource Identifier) pack, descritto in dettaglio in URI pack in WPF.

Questo argomento descrive come configurare e usare i file di dati dell'applicazione.

File di risorse

Se un file di dati deve essere sempre disponibile per un'applicazione, l'unico modo per garantire la disponibilità è compilarlo nell'assembly eseguibile principale dell'applicazione o in uno degli assembly a cui si fa riferimento. Questo tipo di file di dati dell'applicazione è noto come file di risorse.

I file di risorse devono essere utilizzati nei casi seguenti:

  • Non occorre aggiornare il contenuto del file di risorse dopo la relativa compilazione in un assembly.

  • Si desidera semplificare la complessità di distribuzione dell'applicazione riducendo il numero di dipendenze dei file.

  • Il file di dati dell'applicazione deve essere localizzabile (vedere Cenni preliminari sulla globalizzazione e localizzazione WPF).

Nota

I file di risorse descritti in questa sezione sono diversi dai file di risorse descritti in Risorse XAML e diverse dalle risorse incorporate o collegate descritte in Gestire le risorse dell'applicazione (.NET).

Configurazione dei file di risorse

In WPF un file di risorse è un file incluso in un progetto del motore di compilazione Microsoft (MSBuild) come Resource elemento.

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

Nota

In Visual Studio si crea un file di risorse aggiungendo un file a un progetto e impostandolo Build Action su Resource.

Quando il progetto viene compilato, MSBuild compila la risorsa nell'assembly.

Uso dei file di risorse

Per caricare un file di risorse, è possibile chiamare il GetResourceStream metodo della Application classe passando un URI pack che identifica il file di risorse desiderato. GetResourceStream restituisce un StreamResourceInfo oggetto che espone il file di risorse come oggetto Stream e ne descrive il tipo di contenuto.

Ad esempio, il codice seguente illustra come usare GetResourceStream per caricare un Page file di risorse e impostarlo come contenuto di un oggetto Frame (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

Mentre la chiamata GetResourceStream consente di accedere a Stream, è necessario eseguire il lavoro aggiuntivo di conversione nel tipo della proprietà con cui verrà impostata. È invece possibile consentire a WPF di aprire e convertire l'oggetto Stream caricando un file di risorse direttamente nella proprietà di un tipo usando il codice.

Nell'esempio seguente viene illustrato come caricare un oggetto Page direttamente in un oggetto Frame (pageFrame) usando il codice .

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

L'esempio seguente illustra il markup equivalente del precedente esempio.

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

File di codice dell'applicazione come file di risorse

È possibile fare riferimento a un set speciale di file di codice dell'applicazione WPF usando gli URI pack, tra cui finestre, pagine, documenti di flusso e dizionari risorse. Ad esempio, è possibile impostare la Application.StartupUri proprietà con un URI pack che fa riferimento alla finestra o alla pagina da caricare all'avvio di un'applicazione.

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

Puoi farlo quando un file XAML è incluso in un progetto MSBuild come Page elemento.

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

Nota

In Visual Studio si aggiunge un nuovo Windowoggetto , NavigationWindow, Page, FlowDocumento ResourceDictionary a un progetto. Per impostazione predefinita, per Build Action il file di markup si usa Page.

Quando un progetto con Page elementi viene compilato, gli elementi XAML vengono convertiti in formato binario e compilati nell'assembly associato. Di conseguenza, questi file possono essere utilizzati allo stesso modo dei file di risorse tipici.

Nota

Se un file XAML è configurato come Resource elemento e non ha un file code-behind, il codice XAML non elaborato viene compilato in un assembly anziché in una versione binaria del codice XAML non elaborato.

File di dati

Un file di dati viene distribuito come file separato insieme a un assembly eseguibile. Sebbene questi file non vengano compilati in un assembly, dal canto loro gli assembly vengono compilati con i metadati che stabiliscono un'associazione con ciascun file di dati.

È necessario utilizzare i file di dati quando l'applicazione richiede un set specifico di file di dati che possono essere aggiornati senza dover ricompilare l'assembly che li utilizza.

Configurazione dei file di dati

Per aggiungere un file di contenuto a un progetto, è necessario includere un file di dati dell'applicazione come Content elemento. Inoltre, poiché un file di contenuto non viene compilato direttamente nell'assembly, è necessario impostare l'elemento di metadati MSBuild CopyToOutputDirectory per specificare che il file di contenuto viene copiato in un percorso relativo all'assembly compilato. Se si vuole che la risorsa venga copiata nella cartella di output della compilazione ogni volta che viene compilato un progetto, impostare l'elemento CopyToOutputDirectory di metadati con il Always valore . In caso contrario, è possibile assicurarsi che solo la versione più recente della risorsa venga copiata nella cartella di output di compilazione usando il PreserveNewest valore .

Di seguito viene illustrato un file configurato come file di dati, che viene copiato nella cartella dell'output di compilazione solo quando una nuova versione della risorsa viene aggiunta al progetto.

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

Nota

In Visual Studio si crea un file di contenuto aggiungendo un file a un progetto e impostandolo su e impostandolo Build ActionCopy to Output Directory su (uguale Alwaysa ) e Copy if newer (uguale PreserveNewesta Copy always ).Content

Quando il progetto viene compilato, un AssemblyAssociatedContentFileAttribute attributo viene compilato nei metadati dell'assembly per ogni file di contenuto.

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

Il valore di AssemblyAssociatedContentFileAttribute implica il percorso del file di contenuto rispetto alla relativa posizione nel progetto. Ad esempio, se un file di contenuto si trova in una sottocartella di progetto, le informazioni aggiuntive sul percorso verranno incorporate nel AssemblyAssociatedContentFileAttribute valore .

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

Il AssemblyAssociatedContentFileAttribute valore è anche il valore del percorso del file di contenuto nella cartella di output di compilazione.

Uso dei file di contenuto

Per caricare un file di contenuto, è possibile chiamare il GetContentStream metodo della Application classe passando un URI di pacchetto che identifica il file di contenuto desiderato. GetContentStream restituisce un StreamResourceInfo oggetto che espone il file di contenuto come oggetto Stream e ne descrive il tipo di contenuto.

Ad esempio, il codice seguente illustra come usare GetContentStream per caricare un Page file di contenuto e impostarlo come contenuto di (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

Mentre la chiamata GetContentStream consente di accedere a Stream, è necessario eseguire il lavoro aggiuntivo di conversione nel tipo della proprietà con cui verrà impostata. È invece possibile consentire a WPF di aprire e convertire l'oggetto Stream caricando un file di risorse direttamente nella proprietà di un tipo usando il codice.

Nell'esempio seguente viene illustrato come caricare un oggetto Page direttamente in un oggetto Frame (pageFrame) usando il codice .

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

L'esempio seguente illustra il markup equivalente del precedente esempio.

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

File del sito di origine

I file di risorse hanno una relazione esplicita con gli assembly distribuiti insieme, come definito dall'oggetto AssemblyAssociatedContentFileAttribute. Talvolta, è tuttavia possibile che si debba stabilire una relazione implicita o inesistente tra un assembly e un file di dati dell'applicazione, come nei casi seguenti:

  • Un file non esiste in fase di compilazione.

  • I file richiesti dall'assembly non saranno noti fino alla fase di esecuzione.

  • Si desidera avere la possibilità di aggiornare i file senza ricompilare l'assembly al quale sono associati.

  • L'applicazione utilizza file di dati di grandi dimensioni, ad esempio audio e video, che devono essere scaricati dagli utenti unicamente su richiesta.

È possibile caricare questi tipi di file usando schemi URI tradizionali, ad esempio gli file:/// schemi e http:// .

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

Tuttavia, gli schemi e http:// richiedono che l'applicazione file:/// disponga di attendibilità totale. Se l'applicazione è un'applicazione browser XAML (XBAP) avviata da Internet o Intranet e richiede solo il set di autorizzazioni consentite per le applicazioni avviate da tali posizioni, i file separati possono essere caricati solo dal sito di origine dell'applicazione (posizione di avvio). I file di questo tipo sono noti come file del sito di origine.

I file del sito di origine rappresentano l'unica opzione per le applicazioni parzialmente attendibili, benché non siano limitati a questo tipo di applicazione. È possibile che le applicazioni completamente attendibili debbano caricare file di dati dell'applicazione sconosciuti in fase di compilazione. Sebbene queste applicazioni possano utilizzare file:///, è probabile che i file di dati dell'applicazione vengano installati nella stessa cartella dell'assembly dell'applicazione o in una sottocartella di questo. In questo caso è più facile utilizzare un riferimento al sito di origine piuttosto che file:///, poiché l'utilizzo di file:/// richiede l'elaborazione del percorso completo del file.

Nota

I file del sito di origine non vengono memorizzati nella cache con un'applicazione browser XAML (XBAP) in un computer client, mentre i file di contenuto sono. Di conseguenza, vengono scaricati solo se esplicitamente richiesto. Se un'applicazione browser XAML (XBAP) include file multimediali di grandi dimensioni, configurarli come file di origine significa che l'avvio iniziale dell'applicazione è molto più veloce e i file vengono scaricati solo su richiesta.

Configurazione dei file del sito di origine

Se il sito dei file di origine non è esistente o sconosciuto in fase di compilazione, è necessario usare i meccanismi di distribuzione tradizionali per garantire che i file necessari siano disponibili in fase di esecuzione, incluso l'uso del XCopy programma da riga di comando o di Microsoft Windows Installer.

Se si conosce in fase di compilazione i file da individuare nel sito di origine, ma si vuole comunque evitare una dipendenza esplicita, è possibile aggiungere tali file a un progetto MSBuild come None elemento. Come per i file di contenuto, è necessario impostare l'attributo MSBuild CopyToOutputDirectory per specificare che il sito del file di origine viene copiato in un percorso relativo all'assembly compilato, specificando il Always valore o il PreserveNewest valore.

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

Nota

In Visual Studio si crea un file del sito di origine aggiungendo un file a un progetto e impostandolo Build Action su None.

Quando il progetto viene compilato, MSBuild copia i file specificati nella cartella di output della compilazione.

Uso dei file del sito di origine

Per caricare un sito di file di origine, è possibile chiamare il GetRemoteStream metodo della Application classe passando un URI pack che identifica il sito di origine desiderato. GetRemoteStream restituisce un StreamResourceInfo oggetto che espone il file del sito di origine come oggetto Stream e ne descrive il tipo di contenuto.

Ad esempio, il codice seguente illustra come usare GetRemoteStream per caricare un Page file di origine del sito e impostarlo come contenuto di un oggetto 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

Mentre la chiamata GetRemoteStream consente di accedere a Stream, è necessario eseguire il lavoro aggiuntivo di conversione nel tipo della proprietà con cui verrà impostata. È invece possibile consentire a WPF di aprire e convertire l'oggetto Stream caricando un file di risorse direttamente nella proprietà di un tipo usando il codice.

Nell'esempio seguente viene illustrato come caricare un oggetto Page direttamente in un oggetto Frame (pageFrame) usando il codice .

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

L'esempio seguente illustra il markup equivalente del precedente esempio.

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

Ricompilazione in seguito alla modifica del tipo di compilazione

Dopo avere modificato il tipo di compilazione di un file di dati dell'applicazione, è necessario ricompilare l'intera applicazione affinché le modifiche vengano applicate. Se ci si limita a compilare l'applicazione, le modifiche non vengono applicate.

Vedi anche