分類
WPF中的資源分爲兩類:
- 程序集資源
- 對象資源
其中,程序集資源指的是軟件開發中用到的圖片,聲音,xml文件等資源,這些資源被添加到項目中之後會被嵌入到編譯過得程序集中,會被編譯成二進制數據。
而對象資源是一些.NET對象,希望能夠一次定義多次使用,包括畫刷,樣式,模板等。
本文我們將着重介紹程序集資源,下一文我們介紹對象資源
程序集資源介紹
應用程序資源包括 圖片,音頻等應用程序需要使用的文件,他們將被編譯爲二進制文件,內嵌進應用程序中。
添加程序集資源
添加程序集資源需要兩步:
- 將需要的文件添加到項目中
- 將Build Action設置爲Resource
在添加的時候需要注意兩點:
- Build Action中還有一個選項是 Embedded Resource(嵌入的資源)不能選擇這一個
- 之前在WinForm的時代我們會將資源放到項目屬性的Recource選項卡,WPF不支持這種操作,不能使用這種資源
使用程序集資源
在編程中,不管是什麼類型的資源我們都可以使用Application.GetResourceStream來獲取該資源的流,但是實際工作中,獲取了資源的流意義並不大,這個方法太底層了,我們只舉例說明一下這個方法的用法
// 檢索資源
// 方法1:最低級,不分資源類型
StreamResourceInfo sri = Application.GetResourceStream(new Uri("Image/1.jpg", UriKind.Relative));
string type = sri.ContentType; // image/jpg
Stream stream = sri.Stream; // 獲取流
在使用的過程中一般是通過下面的方法
<Image Source="Images/Blue.jpg"/>
// 絕對路徑
img.Source = new BitmapImage(new Uri(@"d:\Photos\Image\1.jpg"));
// 相對路徑
img.Source = new BitmapImage(new Uri("Image/1.jpg", UriKind.Relative));
Build Action:內容
我們之前使用的圖片文件,Build Action選擇了Resource,其中還有其他選項,這裏我們再講一下內容選項,什麼樣的文件需要選擇生成操作爲內容呢?
- 希望安裝之後改動資源文件不重新編譯程序
- 資源文件很大
- 可選的文件,不用隨着程序一起部署
- 資源文件是聲音文件(聲音文件只能引入整個文件,不能使用上面介紹的流的方式來使用)
需要注意的是,生成操作爲內容的文件,其複製到輸出目錄的選項應該改爲始終複製,所以添加一個內容資源需要下面兩步:
- 添加文件,屬性中的生成操作改爲Content(內容)
- 複製到輸出目錄改爲始終複製
使用生成操作爲Content則文件不會被編譯爲二進制,而是直接放置在相應的目錄之下。這一點在保存一些應用程序要讀的json配置文件的時候也可以靈活的運用。
Uri
我們在之前索引資源的時候用到了一個Uri,它是WPF中索引資源的唯一標識,我們需要學習一下Uri的語法,才能夠使用的得心應手
Uri分爲絕對路徑,相對路徑,每種又分爲本程序集,不是本程序集,下面總結一下:
- 本程序集中
// 絕對路徑 Uri uri = new Uri("pack://application:,,,/Subfolder/Resource.xaml", UriKind.Absolute); <Image Source="pack://application:,,,/Subfolder/1.jpg"/> // 相對路徑 Uri uri = new Uri("/Resource.xaml", UriKind.Relative); <Image Source="/Resource.xaml"/>
- 不在本程序集中
// 絕對路徑 Uri uri = new Uri("pack://application:,,,/ReferenceAssembly;component/Subfolder/Resource.xaml", UriKind.Absolute); <Image Source="pack://application:,,,/ReferenceAssembly;component/images/1.jpg"/> // 相對路徑 Uri uri = new Uri(""/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Relative"); <Image Source="/Views;component/images/1.jpg"/>
總結起來就是:
- 要使用絕對路徑需要寫 pack://application,/,這三個逗號是轉義符,實際上是pack://application///
- component作爲分號前面程序集的佔位符
- 相對路徑明顯比絕對路徑簡單
安全
嵌入到應用程序的資源都可以被反編譯出來,使用Reflector就可以反編譯出項目的BAML以及使用的資源