在WPF中顯示一張圖片,本是一件再簡單不過的事情。一張圖片,一行XAML代碼即可。 但是前段時間遇到了一件奇怪的事: 開發機上運行正常的程式,在某些客戶機器上卻顯示不了圖片,而且除了這個問題,其它運行情況都正常。開始排查問題吧,先檢查代碼,然後檢查編譯打包過程,並沒有發現任何問題。再然後去客戶機器上
在WPF中顯示一張圖片,本是一件再簡單不過的事情。一張圖片,一行XAML代碼即可。
但是前段時間遇到了一件奇怪的事:
開發機上運行正常的程式,在某些客戶機器上卻顯示不了圖片,而且除了這個問題,其它運行情況都正常。開始排查問題吧,先檢查代碼,然後檢查編譯打包過程,並沒有發現任何問題。再然後去客戶機器上測試,對應路徑下的圖片是否存在,是否圖片所在路徑的讀寫有問題,還是沒有發現問題。最後發現,當程式移到其它路徑的時候,就一切正常了。而出現錯誤的路徑是:D:\\C#\\ 。這就是今天想說的問題,某些特殊符號(或叫保留字元)對圖片顯示的影響。
首先簡單回顧一下WPF中顯示圖片常用的兩種圖片資源存儲方式:資源 和 內容。資源會被編譯到exe或dll中,使用優勢是速度,簡便。而內容是與exe或dll有顯式關聯的獨立文件,他的使用優勢是靈活。簡單介紹這麼幾句,相信大家都已經很瞭解了。而我的項目因為經常需要用戶自己替換圖片資源文件,所以選擇了“內容”的方式。
在WPF中,不管是資源還是內容的方式,都是通過URI (uniform resource identifier)來標識和載入文件的。大家可以在這裡對URI的構造和解析原理做更多的瞭解:MSDN WPF 中的 Pack URI。而Pack URI 方案由OPC (Open Packaging Conventions)規範使用,該規範利用了RFC 2396的擴展性來定義Pack URI方案。也就是說我們定義的URI必須符合RFC 2396的規定。
Pack URI 的授權組件是一個嵌入式 URI,它指向程式包並且必須符合 RFC 2396。 另外,必須用字元“,”替換字元“/”,並且必須對保留字元(如“%”和“?”)進行轉義。 有關詳細信息,請參見 OPC。
那咱們就來看看這個RFC 2396 中到底對URI做了哪些規定和限制:
先來看一下保留字元:reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," 。顧名思義,這些字元是預留給系統使用的,我們自己的資源URI里不能包含。
再看看哪些字元是被排除的:excluded = "<" | ">" | "#" | "%" | <"> 。這些字元是不允許出現的,來看看RFC 2396中對這幾個字元被排除的解釋吧:
The angle-bracket "<" and ">" and double-quote (") characters are excluded because they are often used as the delimiters
around URI in text documents and protocol fields. The character "#" is excluded because it is used to delimit a URI from a fragment identifier in URI references (Section 4). The percent character "%" is excluded because it is used for the encoding of escaped characters.
看到這裡就很明顯了,我們的圖片因為項目路徑的關係,包含了“#”符號,而圖片又使用了內容的方式,導致URI解析失敗,圖片沒有顯示。
雖然我們自己只寫了一行XAML代碼去實現圖片顯示,但是WPF的Pack URI做了資源分類,解析和文件載入等。
好了,到此為止就已經很明確的知道了導致錯誤的原因了,但是暫時還沒想到解決辦法,只能告訴用戶去規範目錄命名,如果哪位有解決辦法,歡迎回覆賜教,感謝!