WPF 支援三種二進制資源模式,皆可透過統一資源識別符(URI)在 XAML 中存取:
| 建置動作 | 特性 | 部署方式 |
|---|---|---|
| Resource | 嵌入組件內部,打包為 .resources 再編譯進 DLL | 隨組件部署,無需額外檔案 |
| Content | 不嵌入組件,僅在清單記錄路徑 | 檔案必須隨組件複製到輸出目錄 |
| Loose File | 執行期動態決定路徑的鬆散檔案 | 獨立部署,支援絕對路徑或 siteOfOrigin |

<!-- Resource / Content 相對路徑 -->
<Image Source="/a.png" />
<Image Source="/xxx/x.png" />
<!-- 完整 Pack URI -->
<Image Source="pack://application:,,,/a.png" />
<!-- Loose File (siteOfOrigin) -->
<Image Source="pack://siteOfOrigin:,,,/a.png" />
<Image Source="c:\test\a.png" />
<!-- 網路/UNC/檔案協定 -->
<Image Source="https://www.example.com/logo.gif" />
<Image Source="\\server1\share\logo.gif" />
<Image Source="file://c:/test/logo.gif" />
多語言、換膚常用技巧,語法較特殊:
pack://application:,,,/AssemblyName;component/ResourcePath
/AssemblyName 前的斜線component 為關鍵字,必須保留<Image Source="pack://application:,,,/Learn.Library;component/s.gif" />
<Image Source="/Learn.Library;component/s.gif" />
邏輯資源儲存在元素的 Resources 集合中,供子元素透過鍵值引用共享。
<Window.Resources>
<ContentControl x:Key="label1">Hello, World!</ContentControl>
<ImageSource x:Key="image1">/a.png</ImageSource>
</Window.Resources>
<Label Content="{StaticResource label1}" />
<Image Source="{StaticResource image1}" />
資源可為完整 UI 元素,但 Visual 衍生類別只能有一個視覺父元素,多處引用同一資源會拋出例外:
<Window.Resources>
<Image x:Key="image1" Source="/a.png" />
</Window.Resources>
<StaticResource ResourceKey="image1" />
<StaticResource ResourceKey="image1" /> <!-- 錯誤:重複使用視覺元素 -->

解決方案:加上 x:Shared="False",每次引用建立新實例:
<Image x:Key="image1" x:Shared="False" Source="/a.png" />
Resources 集合ResourcesApplication.Resources (App.xaml)SystemParameters 等)同層級資源字典鍵值不可重複,跨層級允許重複,**就近原則**優先採用。
| 特性 | StaticResource | DynamicResource |
|---|---|---|
| 解析時機 | 載入時一次性解析 | 執行期動態查找 |
| 資源變更回應 | 不更新 | 即時反映 |
| 支援完整元素 | 是 | 否(僅限相依屬性值) |
| 前向引用 | 不支援 | 支援 |
<Label Content="{StaticResource label1}" /> <!-- 載入時固定 -->
<Label Content="{DynamicResource label1}" /> <!-- 執行期可變 -->


大型專案可將資源拆分至多個 ResourceDictionary 檔案:
<!-- Dictionary1.xaml -->
<ResourceDictionary xmlns="..." xmlns:x="...">
<ContentControl x:Key="label1">Hello, World!</ContentControl>
</ResourceDictionary>
<!-- Window1.xaml -->
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
<ResourceDictionary Source="Dictionary2.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
合併時若鍵值重複,**後加入的字典優先**。
// 靜態資源
this.labelA.Content = (ContentControl)this.labelA.FindResource("key1");
this.labelA.Content = (ContentControl)this.labelA.TryFindResource("key1"); // 找不到回傳 null
// 動態資源
this.labelB.SetResourceReference(Label.ContentProperty, "key2");