WPF 中的 Pack URI

在 Windows Presentation Foundation (WPF) 中, (uri) 的統一資源識別項可用來識別及載入檔案的方式有很多,包括:

  • 指定 使用者介面 (UI) 要在應用程式第一次啟動時顯示的。

  • 載入影像。

  • 巡覽至頁面。

  • 載入不可執行的資料檔案。

此外,Uri 可以用來識別和載入來自各種不同位置的檔案,包括下列各項:

  • 目前的組件。

  • 所參考的組件。

  • 與組件相對的位置。

  • 應用程式的來源網站。

為了提供一致的機制,從這些位置識別和載入這些類型的檔案,WPF 利用 PACK URI 配置 的擴充性。 本主題提供此配置的總覽,其中涵蓋如何針對各種案例建立套件 Uri、討論絕對和相對 Uri 和 URI 解析,再示範如何從標記和程式碼使用套件 Uri。

套件 URI 配置

套件 URI 配置是由 開放式封裝慣例 (OPC) 規格所使用,其描述用於組織和識別內容的模型。 此模型的重要元素是封裝和元件,其中 封裝 是一或多個邏輯 元件 的邏輯容器。 下圖說明這個概念。

套件和部分圖表

為了識別元件,OPC 規格會利用 RFC 2396 的擴充性 (統一資源識別項 (URI) :一般語法) 定義套件 URI 配置。

URI 所指定的配置是由其前置詞所定義;HTTP、ftp 和 file 都是已知的範例。 套件 URI 配置會使用 "pack" 作為其配置,且包含兩個元件:授權單位和路徑。 以下是套件 URI 的格式。

pack://授權 單位 / 路徑

授權 單位會指定元件所包含的封裝類型,而 路徑 則會指定元件在封裝內的位置。

下圖說明這個概念︰

套件、授權和路徑之間的關聯性

套件和組件與應用程式和檔案類似,其中應用程式 (套件) 可以包括一或多個檔案 (組件),包括︰

  • 編譯為本機組件的資源檔。

  • 編譯為所參考組件的資源檔。

  • 編譯為參考組件的資源檔。

  • 內容檔。

  • 來源網站檔案。

為了存取這些類型的檔案,WPF 支援兩個授權單位: application:///和 siteoforigin:///。 application:/// 授權識別在編譯時期已知的應用程式資料檔,包括資源檔和內容檔。 siteoforigin:/// 授權識別來源網站檔案。 下圖顯示每個授權的範圍。

封裝 URI 圖表

注意

套件 URI 的授權單位元件是指向封裝且必須符合 RFC 2396 的內嵌 URI。 此外,"/" 字元必須取代為 "," 字元,而且必須逸出 "%" 和 "?" 這類保留字元。 如需詳細資料,請參閱 OPC。

下列各節說明如何使用這兩個授權單位來建立套件 Uri,以及用來識別資源、內容和來源網站檔案的適當路徑。

資源檔套件 URI

資源檔會設定為 MSBuild 的 Resource 專案,並編譯為元件。 WPF 支援封裝 Uri 的結構,可用來識別編譯成本機組件的資源檔,或編譯成從本機組件參考的元件。

本機組件資源檔

編譯為本機組件之資源檔的 pack URI 會使用下列授權和路徑:

  • 授權:application:///。

  • 路徑︰相對於本機組件專案資料夾根之資源檔的名稱,包括其路徑。

下列範例 XAML 會顯示位於本機組件專案資料夾根目錄中的資源檔套件 URI。

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

下列範例 XAML 會顯示位於本機組件專案資料夾之子資料夾中的資源檔套件 URI。

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

所參考的組件資源檔

編譯為參考元件之資源檔的 pack URI 會使用下列授權和路徑:

  • 授權:application:///。

  • 路徑:編譯為所參考組件之資源檔的名稱。 路徑必須符合下列格式:

    AssemblyShortName{;版本] {;PublicKey]; 元件/路徑

    • AssemblyShortName:所參考組件的簡短名稱。

    • ;Version [選擇性]:包含資源檔之參考組件的版本。 這是在載入具有相同簡短名稱的兩個以上參考組件時使用。

    • ;PublicKey [選擇性]:用來簽署參考組件的公開金鑰。 這是在載入具有相同簡短名稱的兩個以上參考組件時使用。

    • ;component︰指定從本機組件參考所參考的組件。

    • /Path︰相對於所參考組件專案資料夾根之資源檔的名稱,包括其路徑。

下列範例 XAML 會顯示位於所參考元件專案資料夾根目錄中的資源檔套件 URI。

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

下列範例 XAML 會顯示位於所參考元件專案資料夾之子資料夾中的資源檔套件 URI。

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

下列範例會顯示資源檔的 pack URI,該檔案 XAML 位於所參考、版本特定元件之專案資料夾的根資料夾中。

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

請注意,參考元件資源檔的 pack URI 語法只能與 application:///授權單位搭配使用。 例如,WPF 中不支援下列功能。

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

內容檔套件 URI

內容檔案的 pack URI 會使用下列授權和路徑:

  • 授權:application:///。

  • 路徑:內容檔的名稱,包括其相對於應用程式主要可執行組件之檔案系統位置的路徑。

下列範例會顯示內容檔案的 pack URI XAML ,該檔案位於與可執行檔元件相同的資料夾中。

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

下列範例會顯示內容檔案的 pack URI XAML ,該檔案位於相對於應用程式可執行檔元件的子資料夾中。

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

注意

無法流覽至 HTML 內容檔。 URI 配置只支援導覽至位於來源網站的 HTML 檔案。

來源網站套件 URI

來源網站檔案的 pack URI 會使用下列授權和路徑:

  • 授權:siteoforigin:///。

  • 路徑:來源網站檔案的名稱,包括其相對於從中啟動可執行組件之位置的路徑。

下列範例顯示來源網站檔案的 pack URI XAML ,儲存在可執行檔元件的所在位置。

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

下列範例顯示來源網站檔案的 pack URI XAML ,儲存在相對於啟動應用程式可執行檔元件之位置的子資料夾中。

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

分頁檔

設定為 MSBuild 專案的 XAML 檔案 Page 會以與資源檔相同的方式編譯成元件。 因此, Page 可以使用資源檔的套件 uri 來識別 MSBuild 專案。

XAML通常設定為 MSBuild 專案的檔案類型, Page 具有下列其中一個專案做為其根項目:

絕對與相對套件 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 包含參考 \SUBFOLDER\PAGE2.XAML 的 URI,則參考可以使用下列相對套件 uri。

Page2.xaml

如果 Page1 包含參考 \PAGE2.XAML 的 URI,則參考可以使用下列相對套件 uri。

/Page2.xaml

套件 URI 解析

套件 Uri 的格式讓不同類型的檔案的封裝 Uri 可以看起來相同。 例如,請考慮下列絕對套件 URI。

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

此絕對套件 URI 可以參考本機組件或內容檔案中的資源檔。 下列相對 URI 也是如此。

/ResourceOrContentFile.xaml

為了判斷套件 URI 所參考的檔案類型,WPF 會使用下列啟發學習法來解析本機組件和內容檔案中資源檔的 Uri:

  1. 探查符合套件 URI 之屬性的元件中繼資料 AssemblyAssociatedContentFileAttribute

  2. 如果 AssemblyAssociatedContentFileAttribute 找到屬性,則套件 URI 的路徑會參考內容檔。

  3. 如果 AssemblyAssociatedContentFileAttribute 找不到屬性,請探查編譯成本機組件的集合資源檔。

  4. 如果找到符合套件 URI 路徑的資源檔,則套件 URI 的路徑會參考資源檔。

  5. 如果找不到資源,則會在內部建立的 Uri 無效。

URI 解析不適用於參考下列各項的 Uri:

  • 參考元件中的內容檔案: WPF 不支援這些檔案類型。

  • 參考元件中的內嵌檔案:識別它們的 Uri 是唯一的,因為它們包含參考元件的名稱和 ;component 尾碼。

  • 來源網站檔案:識別它們的 Uri 是唯一的,因為它們是唯一可由包含 siteoforigin:///授權單位之套件 Uri 識別的檔案。

套件 URI 解析所允許的簡化方式,就是讓程式碼與資源和內容檔案的位置稍微無關。 例如,如果本機組件中的資源檔已重新設定為內容檔案,則資源的 pack 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 讓您指定套件 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 類型,例如當使用者在執行時間輸入 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] 說明您可以使用程式碼中指定的各種相對套件 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 中,這些結構會以各種不同的方式來使用,而下列各節涵蓋數個常見的使用方式。

指定要在啟動應用程式時顯示的 UI

StartupUri 指定 UI 要在 WPF 應用程式啟動時顯示的第一個。 針對獨立應用程式, UI 可以是視窗,如下列範例所示。

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

獨立應用程式和 XAML 瀏覽器應用程式 (Xbap) 也可以將頁面指定為初始 UI,如下列範例所示。

<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 可讓應用程式使用各種不同的媒體類型,這些類型都可以使用套件 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 主題的總覽,請參閱設定 樣式和範本

另請參閱