Silverlight 和 WPF

以 Windows 執行階段 XAML 為考量撰寫 Silverlight 和 WPF 應用程式

Pete Brown

 

我們的視覺基本家庭多來愛/Windows 運行庫 (WinRT) 的新 Windows 存儲應用程式的 XAML 是 XAML 和 C# 的最新成員。 這一切與 Microsoft.NET 框架 3.0 和"Avalon"(後來命名視窗演示文稿基礎或 WPF) 2006 年正式開始。 當時的 WPF 中,包括最近的 WPF 4.5,幾個更多的修訂和我們旁邊有七個命名的版本的 Silverlight (包括 1.1 和 5.1) 之後, 幾個版本的 Windows Phone 和更多。 您甚至可以.net 微設備上找到可用的 XAML 堆疊的一部分。

您可能想知道為什麼有這麼多的變化,XAML 和.NET 框架。 雖然許多實現匯聚在類似用途 (例如編寫桌面應用程式的 Silverlight),每個平臺制定和優化不同的方案和目標平臺。 例如,Silverlight 被設計為跨平臺和 Web 承載。 Windows Phone 的 XAML 設計為特定電話的情況和硬體,而且 Windows 8 日 WinRT XAML 針對高性能、 金屬 (x 86 / x 64 和 ARM),觸摸首 (但不是只有觸摸) Windows 存儲應用程式。

不過,這些實現 XAML 有更多中常見的比不。 正是因為這些相似點差異似乎很明顯。 當然,微小的差異會導致大量的發展挑戰,東西我知道從個人經驗和與其他開發人員交談。 然而,我們甚至可以談論在詳細資料級別的相容性的事實說明了語言、 圖書館和標記之間的相似性。

在本文中,我針對兩個很重要的場景:您當前的發展,與同伴 app 和未來校對共用代碼。

伴隨 App 這是 WPF 和 Silverlight 的應用程式開發人員想要為 Windows 8 的同伴 Windows 存儲應用程式制定在同一時間同時共用代碼或跨編譯的情形。

未來校對在此方案中,開發人員今天正在創建新的 WPF 和 Silverlight 的應用程式,但目前並不針對 Windows 8。 當組織採用 Windows 8 時,開發人員希望做好準備 ; 他們想要説明確保適當的他們的應用程式的某些部分將更容易地轉入新的 Windows 使用者介面。

幾十年的程式設計經驗告訴我們重複使用和可攜性是永遠免費。 但是,這裡介紹的技巧,你會發現的許多努力最小的增量超過您通常如何創建架構的應用程式。

周到的體系結構是關鍵

可能只有當你開始有好的體系結構的大型應用程式分成較小的應用程式。 事實上,如果您的應用程式有很多很多沉重的類層次結構的代碼模組之間的相互依賴性,或另有感覺就像一個球的泥或一次性代碼,重用或移植什麼將極為困難。 但不要絕望 ! 可重構代碼,並考慮到新的體系結構可以編寫新代碼。

當設計新的應用程式,我鼓勵 XAML 開發者必須遵循幾種主要方法:具有約束力,模型-視圖-ViewModel (MVVM) 模式和服務類。

具有約束力的越多你擁抱資料繫結時在 XAML 中,發展中國家保持您的邏輯,一件容易分開 UI。 理想情況下,您的 ui,設置 DataCoNtext 和其他一切由具有資料或命令綁定。 在實踐中,幾個應用程式都能夠達到這種程度的分離,但越接近,你的生活將會更容易。

MVVM 模式 MVVM 花樣手--與資料繫結。 ViewModel 是使用者介面將綁定到。 有一噸的巨大的資訊 (和以後,我將涵蓋的工具組) 應可免費在互聯網和書籍中,所以我不會老調重彈,在這裡。

服務類這種做法是不能與 Web 服務相混淆。 相反,這些是在用戶端提供可重複使用的功能的類。 在某些情況下,他們可能會呼喚 RESTful 或其他服務。 在其他情況下,他們可能與您的業務邏輯介面。 在所有情況下,他們將可能不穩定的代碼封裝,並使交換出去更容易的實現。 例如,在圖 1、 ViewModel 談到服務類使用這兩種平臺服務,並解決外部依賴項。

Relationship Between the ViewModel and Service Classes
圖 1 模型和服務類之間的關係

我知道。 你在想,"上頭 ! 另一層圖。"但你知道這些概念是多麼重要。 其目的是要自己脫鉤是在盡可能合理的預算範圍內和時間限制的平臺。 通過分解出的代碼,例如,使 COM 或 p 調用的調用到桌面元素 (如 Windows 成像或 DirectShow,您可以更輕鬆地替換,執行 WinRT 相機 API Windows 存儲應用程式中。 服務類也是絕佳的封裝其他平臺的差異,如合同實現:發送一封電子郵件來自您的 Windows 存儲應用程式會使用一項合同,但在桌上型電腦上它很可能意味著自動化 Outlook 或掛鉤到 SMTP 伺服器。

當然,它很容易過火的體系結構和從未實際交付。 好的建築應該發展更容易,不難。 如果您發現您疲于應付的特定建築模式細枝末節的團隊,很可能在浪費時間。 相反,理解模式和他們所帶來的,然後使智慧和知情決定關於貿易平衡的問題。 在大多數情況下,實施 85%的一個很大的體系結構是比相同的 0%。 同樣,所涉及的實施,最後 15%的成本通常不是值得的。

一旦您分離出與平臺相關的代碼,可以重用,相當多的其他非平凡的代碼。

擁抱新的 Windows 使用者介面設計美學

當開發人員首先考慮建設 Windows 存儲版本的現有 Windows 演示文稿基金會 (WPF) 和 Silverlight 的應用程式,他們立即跑進不得不重新考慮使用者體驗和視覺設計的路障。 對大多數開發人員,右列整個應用程式的前景並不吸引人。 如果你認為 Windows 存儲軟體都是你的未來,有點工作現在擁抱新的 Windows 使用者介面設計美學和準則將真的後支付。

新的 Windows 使用者介面設計提供了一個框架,您可以使用以説明指導您的 UI 設計選擇。 幾個生成 2011年視頻涵蓋 Windows 存儲應用程式設計。 你可以找到它們在 MSDN 通道 9 日 bit.ly/oB56Vf。 此外,這裡是你會想要擁抱新的 Windows 使用者介面設計美學在您的桌面應用程式做的幾件事:

  • 是真實數位。 一般來說,回避的設計 UI,使假類比物理物件 (skeuomorphism) 的做法。 您應避免不只重新創建物理物件,但也派生光澤按鈕、 三維網底、 切合實際的陰影和玻璃背景等技術。
  • 有一個明確的類型層次結構。 不要使用一噸堅持幾個關鍵和輕易分辨大小不同的字體,以及您使用的字體。 標題應輕易分辨從欄位標籤和説明文本。
  • 品牌應用程式。 使用您的顏色、 徽標、 類型和適當的更多。 它有助於有您 Web 開發者和設計者涉及在這裡,因為他們往往有品牌更多親身體驗。
  • 使用一個基於頁面的導航的隱喻。 Silverlight 開發人員會發現這自然 (導航框架是幾乎完全相同),但 WPF 開發人員可能會有多一點的工作要做,要從傳統的 multi-window 和對話方塊的桌面方法。
  • 將專注于任務的。 保持使用者介面任務為重點,並不嘗試補習單個表單上的每一件事。 不幸的是,使用者往往覺得他們想要在單個頁面上,但時間一長,很難使用,每個函數,難以維持,難學。 在某些情況下,考慮大型應用程式分成更小的、 專注于任務的應用程式。
  • 避免不必要的裝飾。 保持簡單的使用者介面。 您想要的工作,他需要重點上,而不適用於功能表、 導航元素、 視窗邊界和其他 chrome 提請使用者的眼睛。

很像您將舊的 Windows 使用者介面設計準則,認為這些概念。 他們是如果您希望您覺得為使用者熟悉和適應新的 Windows 使用者介面的應用程式,您應遵循的準則。 還有更多到它,當然,所以我鼓勵您生成的視頻來看,研究其他開發者和設計者已經編寫的應用程式的示例。

有關使用 UI 樣式的頭開始方式之一就是將 Windows 存儲應用樣式資源複製到您自己的桌面應用程式。 您可以在 Windows 元件資料夾中找到許多樣式資源。 我的電腦上的資料夾位於 C:\Program 檔 (86) \Windows Kits\8.0\Include\winrt\xaml\design。

樣式和資源的一些可用是對。 一些將由於較新的控制項 (ListView 和 GridView,例如),無法使用,另一些可能需要公平略微調整。 然而,這是為您的應用程式獲取現代的外觀和感覺,並促進桌面和 Windows 存儲樣式之間容易過渡的好方法。 甚至當你不能使用樣式或範本直接,你可以從它對您自己的樣式設置工作獲得一個良好的開端。

您的 UI 仍需要一些工作時將其移動到 Windows 運行庫,但如果你現在在您的應用程式接受這些概念,你去朝著確保您的新 Windows 存儲使用者介面和桌面應用程式之間的轉換不刺耳到您的使用者或您的開發人員很長的路。

我所有的較少的工作。 一次樣式應用程式、 方便過渡和現代看作為獎金。

重用代碼和元件

Windows 運行庫在新 Windows 存儲應用程式中獲取了很多關注。 它是新、 它快,有很多很酷的功能。 但是,有時我們會忘記 Windows 運行時不是總和總的你必須使用 ; 使用 XAML 生成 Windows 存儲應用程式使用了大量的 Windows 運行庫和.NET 框架 4.5。 事實上,.NET 框架 4.5 有重大更新,包括許多,使它能夠與 Windows 運行時並行使用。 它仍然是.NET,不過 — — 共用原始程式碼和甚至編譯的二進位檔案,與其他.NET 實現是很合理的做法。

當與 WPF 應用程式共用代碼,你能做的最好的事情現在是編寫 WPF 代碼時,.NET 框架 4.5 與工作。 Windows 存儲應用程式使用.NET 4.5 除了 Windows 運行時安全的子集。 當.NET Framework 提供相同的功能,Windows 運行時 (XAML 是很好的例子),Windows 存儲應用程式的.NET 設定檔使用的 WinRT 版本。 如果你堅持這個盡可能多的子集,您的代碼將非常方便。 當您處理服務和非同步代碼時,可以找到此尤其有用。

當與 Silverlight 共用,你就有點更多的限制,Silverlight 不使用.NET 框架 4.5 或大多數情況下,任務並行庫。 然而,通過針對 Visual Studio 2012 使用者編寫 Silverlight 的應用程式的 Silverlight 5 包的非同步訪問一些任務 <T> 和等待非同步/功能。 添加服務引用代碼不會生成非同步用戶端代碼,但是。 如果這就是對你很重要,可以移植到 Silverlight 的代碼生成的代理。 更好的方法,在這裡,使用的體系結構,我建議是封裝內本機服務類的 Web 服務交互。

是完全相同的代碼呢? 模型的類 — — 和在許多情況下,ViewModel 類 — — 屬於此類。 在這裡,您有兩個選擇:可擕式類圖書館 (PCL) 專案和連結的專案。

PCL 專案 PCL 是共用不同.NET 目標之間已編譯的 Dll 的好方法。 PCL 使您能夠共用組件之間.NET、.NET 為 Windows 存儲應用程式、 Silverlight、 Windows Phone 和更多。 若要使用 PCL,您需要限制對相容性清單中的那些程式集的引用。 瞭解更多有關在 PCL bit.ly/z2r3eM

連結共用原始程式碼和條件編譯的專案這是 Visual Studio 功能,使您可以擁有多個專案,每個面向不同的平臺,但與單個共用原始程式碼的副本。 在過去,我使用這種方法主要是在共用 ASP.NET 伺服器上的和用戶端上的 Silverlight 之間的代碼時。 我在博客上可以找到一個示例 bit.ly/RtLhe7

雖然我我再利用方案的大多數傳統上使用過連結的專案,PCL 已真的長大了在新的版本。 如果您要吸引 WPF 和 WinRT XAML,PCL 會讓你幾乎所有的東西在.NET 4.5 設定檔中使用 Windows 存儲的應用程式。 當有疑問,從開始 PCL。

我喜歡有關連結的專案方法的一件事是我可以提供特定于平臺的附加功能通過分部類和條件編譯。 在專案屬性頁中的生成選項卡上設置的條件編譯符號所示圖 2

Project Properties Page Showing Compilation Symbols
圖 2 顯示編譯符號的專案屬性頁

預設情況下,大量的條件編譯符號為您定義,如中所示圖 3

圖 3 條件編譯符號

平台 編譯符號
Windows 運行庫 +.NET 框架 NETFX_CORE
WPF/.NET 框架 4.5 桌面 (無)
Silverlight SILVERLIGHT

.NET Framework 全沒有定義任何編譯符號的注意 — — 它審議了缺省的平臺。 如果這讓你不安,您可以添加您自己編譯符號 ; 只需確保你做,.NET 框架的所有專案中您的解決方案。

條件編譯也是如何,在代碼中,您可以將不同的命名空間,具體取決於目標平臺中:

#if NETFX_CORE
using Windows.UI.Xaml;
#else
using System.Windows.Xaml;
#endif

在任何非平凡的應用程式,您可能會發現自己的共用代碼使用 PCL 和連結的專案。 但是,共用 XAML,是更複雜。

共用 XAML Ui 和資源

原因有幾個更難比共用代碼共用 XAML。 所以做最重要的步驟是定制的介面的外形和你的目標的平臺。 (見"擁抱新 Windows 使用者介面設計美學"的一些指標在這裡)在大多數情況下,您的開發時間更好地用於確保代碼可重複使用,因為你可以看到更多回報少的努力。 不過,會有欲望和在專案間共用 XAML 的傾向。

XAML 沒有概念的條件編譯。 其結果是,命名空間差異是更難管理比在代碼中。 除了自己的命名空間,您將它們導入 XAML 的方式 WinRT XAML 和其他版本之間發生了更改。

請考慮此.NET 框架 XAML:

xmlns:localControls="clr-namespace:WpfApp.Controls"

與此 WinRT XAML:

xmlns:localControls="using:WindowsApp.Controls"

而不是"clr 命名空間"語句,WinRT XAML"使用"聲明在 XAML 中時,使用導入的命名空間。 產品團隊為什麼做這個? 在 XAML 中的導入命名空間可能來自非 CLR 代碼 — — c + + 示例。 不僅你現在對 XAML 支援 c + +,而且可以在 c + + 編寫擴展程式集並在.NET 代碼中使用它們。 這意味著"clr 命名空間"一詞是不再準確。

一種方法來處理差異是動態載入 XAML。 早在 Silverlight 1.1 Alpha 天,這是生成使用者控制項的方式:XAML 是動態地載入和運行時處理。 自那時以來,這種方法已經被各應用程式開發商的靈活性跨所有平臺。

動態載入 XAML 時您正在使用的字串。 這意味著您可以替換或子集上的文本將載入到視覺化樹之前。 例如,假設您有一個空的 usercontrol 定義 WPF 或 Silverlight 專案中。 Usercontrol 是剛才定義的命名空間和類的殼。 然後 WinRT XAML 專案中有相當的外殼。

這裡是.NET XAML:

<UserControl x:Class="WpfApp.Controls.AddressControl"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
  <Grid x:Name="LayoutRoot">
  </Grid>
</UserControl>

而且這裡是 WinRT XAML:

<UserControl x:Class="WindowsApp.AddressControl"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
  <Grid x:Name="LayoutRoot">
  </Grid>
</UserControl>

兩個 XAML 使用者控制項是平原-老-香草範本輸出。 我所作的更改只是給網格的根項目名稱和刪除一些未使用的命名空間,以保持短代碼。 代碼隱藏的控制項可以共用使用的代碼共用的技術,雖然代碼劃分到單獨的共用類,只要有可能,我建議。

然後,若要在運行時載入 XAML,可以使用類似于中看到的內容的代碼圖 4

圖 4 為動態載入 XAML 代碼

public partial class AddressControl : UserControl
{
  public AddressControl()
  {
    InitializeComponent();
    LoadXaml();
  }
  private void LoadXaml()
  {
    string xaml =
    "<Grid xmlns=\"https://schemas.microsoft.com/winfx/2006/xaml/presentation\" " +
      "xmlns:x=\"https://schemas.microsoft.com/winfx/2006/xaml\">" +
      "<Grid.RowDefinitions>" +
        "<RowDefinition Height=\"Auto\" />" +
        "<RowDefinition Height=\"30\" />" +
      "</Grid.RowDefinitions>" +
      "<TextBlock Text=\"Address\" Grid.Row=\"0\" FontSize=\"10\" />" +
      "<TextBox x:Name=\"t1\" Grid.Row=\"1\" FontSize=\"15\" />" +
    "</Grid>";
    var reader = new StringReader(xaml);
    var xmlReader = XmlReader.Create(reader);           
    LayoutRoot.Children.Add((UIElement)XamlReader.Load(xmlReader));
  }
}

要在 WinRT XAML 載入的代碼更加容易,這是直接字串載入支援的:

string xaml = "..."
LayoutRoot.Children.Add((UIElement)XamlReader.Load(xaml));

為簡單起見,我從這裡的硬編碼字串載入 XAML 和使用 XAML,已經是可擕式並不需要任何字串操作。 關於前者,如果你想要的設計器支援,使從 XAML 資源檔中載入文本的代碼。 然後,包括所有常用類和 xlmns 定義,以支援設計器,但它們扔掉在 XAML 載入步驟。

不管如何 XAML 獲取視覺化樹中,如果您想要鋼絲動態載入 XAML 中的事件,這可以從代碼以及:

LayoutRoot.Children.Add((UIElement)XamlReader.Load(xaml));
var t1 = FindName("t1") as TextBox;
if (t1 != null)
{
  t1.TextChanged += t1_TextChanged;
}

正如您可以載入 XAML UI,也可以在運行時載入的資源。 您可以從頭開始創建它們,或使用此處,顯示的相同方法載入它們從 XAML 源:

private void LoadResources()
{
  string xaml =
    "<Style xmlns=\"https://schemas.microsoft.com/winfx/2006/xaml/presentation\" " +
      "TargetType=\"TextBox\">" +
      "<Setter Property=\"Margin\" Value=\"5\" />" +
    "</Style>";
  // Implicit styles use type for key
  var key = typeof(TextBox);
  App.Current.Resources.Add(key, XamlReader.Load(xaml));
}

當動態載入資源,一定要有他們之前他們正在引用載入。 如果存在隱式的樣式,他們只是不會適用于已經在視覺化樹中的任何內容創建資源時。

很明顯,這整個的做法是有一點是,它不會在每種情況下工作順利。 (在某些時候,字串操作可以是更多的工作,而不是價值)。但如果你想要最大限度的跨平臺重用,這是一個可能的方式來完成它。 就個人而言,我會用這只為關鍵的 UI 元件的正在改變了很多或太複雜或太多,只需複製並粘貼定期。

當然,您也可以編寫自訂生成操作或其他 Visual Studio 擴展來自動處理該過程時保存檔的簽出、 建造或其他一些步驟。

最後一種方法是完全避免 XAML 並轉而從代碼創建整個 UI。 通常情況下,我告誡這種方法對於大多數應用程式 — — 這是大量的額外工作,並且您得到零的設計器支援。 但是,資料驅動的 Ui 操作非常好用這種方法。 如果你可以在 XAML 中創建它,您可以創建它在代碼中,如中所示的 XAML WinRT 圖 5

與 WinRT XAML 創建 UI 的圖 5

private void CreateControls()
{
  Grid g = new Grid();
  RowDefinition r1 = new RowDefinition();
  RowDefinition r2 = new RowDefinition();
  r1.Height = new GridLength(1, GridUnitType.Auto);
  r2.Height = new GridLength(30.0);
  g.RowDefinitions.Add(r1);
  g.RowDefinitions.Add(r2);
  TextBlock t = new TextBlock();
  t.Text = "Address";
  Grid.SetRow(t, 0);
  TextBox tb1 = new TextBox();
  Grid.SetRow(tb1, 1);
  g.Children.Add(t);
  g.Children.Add(tb1);
  LayoutRoot.Children.Add(g);
}

此代碼中的,除了字體設置 (以保持短上市),相當於將 TextBlock 和文字方塊添加到 LayoutRoot 網格中,網格中所載的動態載入的 XAML。

考慮開放原始碼工具組

許多最佳 XAML 的 C# 工具組是開放原始碼。 積極開放源碼專案中你可能會看到拾取並添加類型的功能,可使 Silverlight、 WPF 和 Windows 運行庫之間移動可能感興趣的人。

有大量的 MVVM 工具組,例如,多數是可擕式跨不同口味的 XAML。 通過使用其中一種,可以説明減少您的原始程式碼時你分享或將它移植所需的更改的數量。 同樣地,你會發現控制項、 本機資料庫和其他可用的工具組使用跨平臺。

總是有一種風險開放原始碼開發人員不會工作到目標新版本的平臺,但對原始程式碼的訪問,您可以叉代碼,考慮這你要。 回來當您完成時,只是貢獻代碼。

決定一個 Windows 存儲應用程式使用者介面

當創建新的 Windows 存儲應用程式時,請記住,不是所有方面的所有桌面應用程式直接都轉化為 Windows 存儲的應用程式。 例如,300 的形式,為不同的使用者,執行不同的功能將整個套件的大型應用程式不一定是新的 Windows 使用者介面的候選者。 相反,應該專注于任務的和針對特定使用 Windows 存儲的應用程式。

考慮保險申請。 您可能有一個應用程式在公司是由大量的使用者共用。 它可以處理使用者的安全管理的監督職能。 它允許通過電話,同時該欄位在可擕式電腦上還應考慮玻璃損壞的索賠。 它有內置功能,創建新策略,等等。

如果你分手成數目專注于任務的 (或使用者聚焦) 較小的應用程式的應用程式,它將更適合於新的 Windows 使用者介面。 例如,您可能希望特別著重考慮下,現場事故資訊單獨欄位調節器 app。 因為它關注的它包括對拍攝和錄製視頻,以及本機快取已中斷連線或窮人信號領域的資料支援。 這個應用程式可能與其他應用程式在企業中,共用大量的代碼,但其重點輕鬆定制生成它的方案。

總結

WinRT XAML Silverlight 和 WPF 已創建具有不同的用途,記住,但他們更類似于不同。 共用它們之間的代碼非常簡單,並且共用 XAML 是可能。 有很多可以遵循所有三個平臺為目標,並從桌面移動到新的 Windows 存儲使用者介面的其他技術。 我很想繼續此對話,在 Twitter 上和我在博客上 10rem.net。 如果您已經使用其他技術的多目標或移植代碼到 Windows 運行時,我很想聽聽你。

Pete Brown 是在 Microsoft Windows 8 XAML 和小工具的傢伙。他也是"Silverlight 5 在行動"(曼甯出版物,2012年) 和"Windows 8 XAML 中行動"(曼甯出版物,2012年) 的作者。他的博客和網站 10rem.net, ,您可以按照他在 Twitter 上 twitter.com/pete_brown

由於以下的技術專家對本文的審閱:蒂姆豪雅