今天在這里跟大家聊聊關於 Windows Universal 應用誇平台的問題,首先Universal Windows App的定義相信大家已經有所了解了(如果你是一個剛剛接觸 Universal APP 的開發這個請先閱讀一下我之前的文章 Windows Phone 8.1 開發技術概覽 [Universal APP]), 相信大家在這里最苦惱的事情莫過於在不同開發架構下分享代碼了,今天我在這里給大家推薦一個解決方案使用可移植類庫(Portable Class Library)在不同的Windows項目之間分享代碼。(Windows 8.1 / Windows Phone 8.1 )這里還包括Silverlight開發的 Windows Phone 8.1 應用。
首先介紹一下什么是 Portable Class Library,稱之為‘可移植類庫’(簡稱PCL)支持 C# 語言開發,並且在開發 Universal 類庫時支持UI呈現。 這里在次強調一下目前只支持C#開發,C# 的語法可以在 PCL 中使用,方便C# 的開發人員快速上手,並且支持調用 Windows Runtime 的 SDK 例如,網絡訪問,JSON 處理,內容分享等功能。 也非常適合三方SDK開發和功能集成。
如何創建一個 PCL 的類庫呢非常簡單只需要打開我們的VS2013(update 2 及以上版本)選擇Universal 應用模板 選擇PCL的項目模板即可,(Component支持 Universal 應用。 DLL 支持Silverlight以及 Windows XAML C# 應用)這里最大的區別是 DLL 的類庫不允許類庫中使用UI內容。(原因非常簡單 Universal 應用和 SL的應用架構不同)
通過項目屬性 我們還可以通過 Output Type 來切換項目的輸出類型(Component 或 DLL)
另外 我們還可以是通過 Targets 屬性來適配應用的應用適配平台,這里要注意的是如果應用跨 Universal 和 Silverlight 平台 (8.0 和 8.1)類庫內容會受到很大的影響(類庫版本越舊我們在PCL中可以使用的WinRT feature 也就越少),並且PCL 將不能支持UI控件的分享。
上面提到各種限制肯能有些復雜,我用一張圖來給大家說明一下。(這里針對Universal 8.1 APP 和 Silverlight 應用架構)
1.如果你的類庫只想被Universal 應用調用,那么你需要選擇 Windows Runtime Component 進行輸出,你的PCL將支持大部分 Windows RT的 Feature 並且支持UI控件的分享,但是WinJS項目不支持 UI 控件的展示,這里原因很簡單 XAML上層渲染和 HTML是不同的。
2.如果你需要你的PCL支持 Silverlight 項目的調用,那么你需要選擇 Class Library (DLL)進行輸出,你的PCL也可以支持大部分 Windows RT的 Feature 。但是不可以進行 UI控件的分享,並且你輸出的DLL將不能被 Universal APP的 C++ XAML 和 HTML WinJS 項目調用。
這里最好的建議就是相同的類庫,如果想讓它同時兼容 Universal 架構(XAML C++/C# 和 HTML WinJS)Silverlight架構,只需要將PCL的輸出類型切換在編譯一次就可。(三方SDK建議這樣做:))
我這里給大家一個測試代碼是使用 WinRT中的Share Contract 進行應用間分享。(因為沒有 UI 內容可以直接 Target 到 Universal 和 Silverlight 項目中去,當然是兩次編譯)
項目結構(為了方便這里我做了 Component 和 DLL 的項目但是項目中的代碼是相同的,當然在開發的時候用link的形勢也可以)
PCL 分享類庫代碼如下
public sealed class ShareText { private DataTransferManager dataTransferManager; public string DataContent { get; set; } public ShareText() { this.dataTransferManager = DataTransferManager.GetForCurrentView(); this.dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.OnDataRequested); DataContent = "Share Text From PCL"; } private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs e) { // Call the scenario specific function to populate the datapackage with the data to be shared. if (GetShareContent(e.Request)) { // Out of the datapackage properties, the title is required. If the scenario completed successfully, we need // to make sure the title is valid since the sample scenario gets the title from the user. if (String.IsNullOrEmpty(e.Request.Data.Properties.Title)) { return; } } } public bool GetShareContent(DataRequest request) { bool succeeded = false; string dataPackageText = DataContent; if (!String.IsNullOrEmpty(dataPackageText)) { DataPackage requestData = request.Data; requestData.Properties.Title = "Share Text"; requestData.Properties.Description = "Share Description"; // The description is optional. //requestData.Properties.ContentSourceApplicationLink = GetType().Name; requestData.SetText(dataPackageText); succeeded = true; } else { request.FailWithDisplayText("Enter the text you would like to share and try again."); } return succeeded; } public void ShowShareUI() { // If the user clicks the share button, invoke the share flow programatically. DataTransferManager.ShowShareUI(); } }
C# 項目調用
private void Button_Click(object sender, RoutedEventArgs e) { UniversalComponent.ShareText st = new UniversalComponent.ShareText(); st.DataContent = "Hello PCL form C#"; st.ShowShareUI(); }
C++ 項目調用
void UniversalC__App::BlankPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { UniversalPCL::ShareText^ ST = ref new UniversalPCL::ShareText; ST->DataContent = "Hello PCL from C++"; ST->ShowShareUI(); }
HTML + WinJS項目調用
function callComponent() {
var component = new UniversalPCL.ShareText(); component.dataContent = "Hello form JS"; component.showShareUI(); }
Silverlight C# 調用
private void Button_Click(object sender, RoutedEventArgs e) { UniversalComponent.ShareText st = new UniversalComponent.ShareText(); st.DataContent = "Hello PCL form SL"; st.ShowShareUI(); }
我們可以在 VS 中測試任意一個平台的調用情況
這里我就不逐一展示測試效果了,貼一張 C++ 調用的截圖讓大家過過癮也好 :)
希望上的總結可以幫助到大家, 同時歡迎大家在這里和我溝通交流或者在新浪微博上 @王博_Nick









