WPF學習之路初識
WPF 介紹
Windows Presentation Foundation (WPF) 是下一代顯示系統,用於生成能帶給用戶震撼視覺體驗的 Windows 客戶端應用程序。 使用 WPF,您能夠建立普遍的獨立應用程序以及瀏覽器承載的應用程序。示例包括下圖中顯示的 Contoso Healthcare Sample Application(Contoso Healthcare 示例應用程序)。javascript
![Contoso Healthcare UI 示例 Contoso Healthcare UI 示例](http://static.javashuo.com/static/loading.gif)
WPF 的核心是一個與分辨率無關而且基於向量的呈現引擎,旨在利用現代圖形硬件的優點。WPF 經過一整套應用程序開發功能擴展了這個核心,這些功能包括可擴展應用程序標記語言 (XAML)、控件、數據綁定、佈局、二維和三維圖形、動畫、樣式、模板、文檔、媒體、文本和版式。WPF 包含在 Microsoft .NET Framework 中,使您可以生成融入了 .NET Framework 類庫的其餘元素的應用程序。 html
WPF 做爲 .NET Framework 類型的一個子集存在,這些類型大多位於 System.Windows 命名空間。若是您之前已使用 .NET Framework 經過諸如 ASP.NET 和 Windows 窗體之類的託管技術生成應用程序,那麼您應該熟悉 WPF 的基本編程體驗;您可使用您最喜好的 .NET Framework 編程語言(如 C# 或 Visual Basic)實例化類、設置屬性、調用方法以及處理事件。 java
WPF 爲 Windows 客戶端應用程序開發提供了更多編程加強功能。 一個明顯的加強功能就是使用標記和代碼隱藏開發應用程序的功能,ASP.NET 開發人員應該熟悉此體驗。 您一般使用可擴展應用程序標記語言 (XAML) 標記實現應用程序的外觀,而使用託管編程語言(代碼隱藏)實現其行爲。 這種外觀和行爲的分離具備如下優勢:git
-
下降了開發和維護成本,由於外觀特定的標記並無與行爲特定的代碼緊密耦合。 web
-
開發效率更高,由於設計人員能夠在開發人員實現應用程序行爲的同時實現應用程序的外觀。 算法
-
可使用多種設計工具實現和共享 XAML 標記,以知足應用程序開發參與者的要求;Microsoft Expression Blend 提供了適合設計人員的體驗,而 Visual Studio 2005 針對開發人員。 chrome
-
WPF 應用程序的全球化和本地化得以大大簡化(請參見 WPF 全球化和本地化概述)。 express
標記
XAML 是一種基於 XML 的標記語言,用於以聲明的方式實現應用程序的外觀。它一般用於建立窗口、對話框、頁面和用戶控件,並用控件、形狀和圖形填充它們。 編程
下面的示例使用 XAML 實現一個窗口的外觀,該窗口中只包含一個按鈕。 canvas
具體而言,此 XAML 分別使用 Window 和 Button 元素定義一個窗口和一個按鈕。 每一個元素均配置了特性,如 Window 元素的 Title 特性,用於指定窗口的標題欄文本。在運行時,WPF 將標記中定義的元素和特性轉換爲 WPF 類的實例。 例如,Window 元素被轉換爲 Window 類的實例,該類的 Title 屬性是 Title 特性的值。
下圖演示了 XAML 在上一示例中定義的用戶界面 (UI)。
![包含按鈕的窗口 包含按鈕的窗口](http://static.javashuo.com/static/loading.gif)
參見 XAML 概述 (WPF)。
因爲 XAML 基於 XML,所以使用它來編寫的 UI 被組合到稱爲「元素樹」的嵌套元素層次結構中。 元素樹爲建立和管理 UI 提供了一種邏輯且直觀的方式。 有關更多信息,請參見 WPF 中的樹。
代碼隱藏
應用程序的主要行爲是實現響應用戶交互的功能,包括處理事件(如,單擊菜單、工具欄或按鈕),並調用業務邏輯和數據訪問邏輯做爲響應。 在 WPF 中,此行爲一般在與標記關聯的代碼中實現。 此類代碼稱爲「代碼隱藏」。 下面的示例演示上一示例中的代碼隱藏和更新的標記。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.AWindow" Title="Window with Button" Width="250" Height="100"> <!-- Add button to window --> <Button Name="button" Click="button_Click">Click Me!</Button> </Window>
Namespace SDKSample Partial Public Class AWindow Inherits System.Windows.Window Public Sub New() ' InitializeComponent call is required to merge the UI ' that is defined in markup with this class, including ' setting properties and registering event handlers InitializeComponent() End Sub Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Show message box when button is clicked MessageBox.Show("Hello, Windows Presentation Foundation!") End Sub End Class End Namespace
using System.Windows; // Window, RoutedEventArgs, MessageBox namespace SDKSample { public partial class AWindow : Window { public AWindow() { // InitializeComponent call is required to merge the UI // that is defined in markup with this class, including // setting properties and registering event handlers InitializeComponent(); } void button_Click(object sender, RoutedEventArgs e) { // Show message box when button is clicked MessageBox.Show("Hello, Windows Presentation Foundation!"); } } }
在此示例中,代碼隱藏實現一個從 Window 類派生的類。 x:Class 特性用於將標記與代碼隱藏類相關聯。 InitializeComponent 是從代碼隱藏類的構造函數中調用的,用於將標記中定義的 UI 與代碼隱藏類相合並。 (生成應用程序時將爲您生成 InitializeComponent,所以您不須要手動實現它。)x:Class 和 InitializeComponent 的組合確保您的實現不管什麼時候建立都能獲得正確的初始化。 代碼隱藏類還爲按鈕的 Click 事件實現了一個事件處理程序。 當單擊該按鈕時,事件處理程序將經過調用 MessageBox.Show 方法顯示一個消息框。
下圖演示了單擊按鈕後的結果。
![消息框 消息框](http://static.javashuo.com/static/loading.gif)
.NET Framework、System.Windows、標記和代碼隱藏構成了 WPF 應用程序開發體驗的基礎。 此外,WPF 還爲創造具備豐富內容的用戶體驗提供了全面的功能。 爲了打包此內容並將其做爲「應用程序」發送給用戶,WPF 提供了一些類型和服務,它們統稱爲「應用程序模型」。 該應用程序模型既支持開發獨立應用程序,也支持開發瀏覽器承載的應用程序。
獨立應用程序
對於獨立應用程序,您可使用 Window 類建立可從菜單欄和工具欄上訪問的窗口和對話框。 下圖演示了帶有一個主窗口和一個對話框的獨立應用程序。
![主窗口和對話框 主窗口和對話框](http://static.javashuo.com/static/loading.gif)
此外,您還可使用如下 WPF 對話框:MessageBox、OpenFileDialog、SaveFileDialog 和 PrintDialog。
瀏覽器承載的應用程序
對於瀏覽器承載的應用程序(稱爲 XAML 瀏覽器應用程序 (XBAP)),您能夠建立可以使用超連接(Hyperlink 類)導航的頁面 (Page) 和頁函數 (PageFunction<T>)。 下圖演示了 Internet Explorer 7 承載的 XBAP 中的頁面。
![所承載的應用程序的兩頁 所承載的應用程序的兩頁](http://static.javashuo.com/static/loading.gif)
WPF 應用程序既能夠承載於 Microsoft Internet Explorer 6 中,也能夠承載於 Internet Explorer 7 中。 WPF 提供瞭如下兩個選項做爲替代導航宿主:
-
Frame ,用於承載頁面或窗口中可導航內容的孤島。
-
NavigationWindow ,用於承載整個窗口中的可導航內容。
參見導航概述。
應用程序類
XBAP 和獨立應用程序一般很是複雜,須要額外的應用程序範圍的服務,包括啓動和生存期管理、共享屬性以及共享資源。Application 類封裝了這些服務以及更多內容,而且只需使用 XAML 便可實現,以下面的示例所示。
此標記是獨立應用程序的應用程序定義,並指示 WPF 建立一個在應用程序啓動時自動打開 MainWindow 的 Application 對象。
理解 Application 的一個關鍵概念在於,它爲獨立應用程序和瀏覽器承載的應用程序提供了一個通用的支持平臺。 例如,瀏覽器承載的應用程序可使用前面的 XAML,以便在 XBAP 啓動時自動導航到某個頁面,以下面的示例所示。
有關更多信息,請參見應用程序管理概述。
安全性
因爲 XBAP 承載於瀏覽器中,所以安全性相當重要。 特別是,XBAP 使用部分信任的安全性沙盒強制施加限制,這些限制少於或等於對基於 HTML 的應用程序所施加的限制。 此外,能夠從部分信任的 XBAP 中安全運行的每一個 HTML 功能都使用全面的安全進程進行了測試,WPF 安全策略 — 安全工程中對此進行了詳細介紹。
儘管如此,大部分 WPF 功能仍可以從 XBAP 中安全執行,如 WPF 部分信任安全中所述。
應用程序模型提供的用戶體驗是構造控件。 在 WPF 中,「控件」是一個總括性術語,適用於窗口或頁面中承載的、具備用戶界面 (UI) 而且實現某些行爲的一種 WPF 類。
參見控件。
按功能分類的 WPF 控件
此處列出了內置的 WPF 控件。
-
按鈕:Button 和 RepeatButton。
-
日期顯示和選擇:Calendar 和 DatePicker。
-
數字墨跡:InkCanvas 和 InkPresenter。
-
文檔:DocumentViewer、FlowDocumentPageViewer、FlowDocumentReader、FlowDocumentScrollViewer 和 StickyNoteControl。
-
輸入:TextBox、RichTextBox 和 PasswordBox。
-
佈局:Border、BulletDecorator、Canvas、DockPanel、Expander、Grid、GridView、GridSplitter、GroupBox、Panel、ResizeGrip、Separator、ScrollBar、ScrollViewer、StackPanel、Thumb、Viewbox、VirtualizingStackPanel、Window 和 WrapPanel。
-
菜單:ContextMenu、Menu 和 ToolBar。
-
選擇:CheckBox、ComboBox、ListBox、RadioButton 和 Slider。
-
用戶信息:AccessText、Label、Popup、ProgressBar、StatusBar、TextBlock 和 ToolTip。
建立 UI 時,您經過按位置和大小排列控件來造成一種佈局。 任何佈局的主要要求都是適應窗口大小和顯示設置的變化。 WPF 爲您提供了一個一流的可擴展布局系統,而不是強制您編寫代碼以使佈局適應這些狀況。
佈局系統的基礎是相對定位,它提升了適應窗口和顯示條件變化的能力。 此外,佈局系統還管理控件之間的協商以肯定佈局。 協商過程分爲兩步:第一步,控件向父控件通知它所需的位置和大小;第二步,父控件通知該控件它能夠具備多大空間。
佈局系統經過基本 WPF 類公開給子控件。對於通用的佈局,如網格、堆疊和停靠,WPF 包括了幾個佈局控件:
-
Canvas :子控件提供其本身的佈局。
-
DockPanel :子控件與面板的邊緣對齊。
-
Grid :子控件按行和列放置。
-
StackPanel :子控件垂直或水平堆疊。
-
VirtualizingStackPanel :子控件被虛擬化,並沿水平或垂直方向排成一行。
-
WrapPanel :子控件按從左到右的順序放置,若是當前行中的控件數多於該空間所容許的控件數,則換至下一行。
下面的示例使用 DockPanel 排列幾個 TextBox 控件。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.LayoutWindow" Title="Layout with the DockPanel" Height="143" Width="319"> <!--DockPanel to layout four text boxes--> <DockPanel> <TextBox DockPanel.Dock="Top">Dock = "Top"</TextBox> <TextBox DockPanel.Dock="Bottom">Dock = "Bottom"</TextBox> <TextBox DockPanel.Dock="Left">Dock = "Left"</TextBox> <TextBox Background="White">This TextBox "fills" the remaining space.</TextBox> </DockPanel> </Window>
DockPanel 容許子 TextBox 控件通知它如何排列這些子控件。 爲此,DockPanel 實現一個 Dock 屬性,該屬性公開給子控件,以便每一個子控件指定一個停靠樣式。
下圖演示了上一示例中 XAML 標記的結果。
![DockPanel 頁 DockPanel 頁](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見佈局。 有關介紹性示例,請參見 WPF Layout Gallery Sample(WPF 佈局庫示例)。
建立大多數應用程序的目的是爲用戶提供查看和編輯數據的方式。 對於 WPF 應用程序,存儲和訪問數據的工做已經由 Microsoft SQL Server 和 ADO.NET 之類的技術提供。 訪問數據並將數據加載到應用程序的託管對象中後,WPF 應用程序的複雜工做纔開始。 實質上它涉及到兩個步驟:
-
將數據從託管對象複製到控件中,在控件上能夠顯示和編輯數據。
-
確保將使用控件對數據進行的更改複製回託管對象。
爲了簡化應用程序開發,WPF 提供了一個數據綁定引擎以自動執行這些步驟。數據綁定引擎的核心單元是 Binding 類,它的任務是將控件(綁定目標)綁定到數據對象(綁定源)。 下圖說明了這種關係。
![基本數據綁定示意圖 基本數據綁定示意圖](http://static.javashuo.com/static/loading.gif)
下面的示例演示如何將 TextBox 綁定到自定義 Person 對象的實例。 下面的代碼演示了 Person 的實現。
下面的標記將 TextBox 綁定到自定義 Person 對象的實例。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.DataBindingWindow"> ... <!-- Bind the TextBox to the data source (TextBox.Text to Person.Name) --> <TextBox Name="personNameTextBox" Text="{Binding Path=Name}" /> ... </Window>
Imports System.Windows ' Window Namespace SDKSample Partial Public Class DataBindingWindow Inherits Window Public Sub New() InitializeComponent() ' Create Person data source Dim person As Person = New Person() ' Make data source available for binding Me.DataContext = person End Sub End Class End Namespace
在此示例中,Person 類在代碼隱藏中實例化,並被設置爲 DataBindingWindow 的數據上下文。 在標記中,將 TextBox 的 Text 屬性綁定到 Person.Name 屬性(使用「{Binding ... }」XAML 語法)。 此 XAML 通知 WPF 將 TextBox 控件綁定到存儲在窗口的 DataContext 屬性中的 Person 對象。
WPF 數據綁定引擎還提供了其餘支持,包括驗證、排序、篩選和分組。 此外,當標準 WPF 控件顯示的 UI 不合適時,數據綁定還支持使用數據模板爲綁定的數據建立自定義 UI。
有關更多信息,請參見數據綁定概述。 有關介紹性示例,請參見 Data Binding Demo(數據綁定演示)。
WPF 引進了一組普遍的、可伸縮且靈活的圖形功能,它們具備如下優勢:
-
與分辨率和設備無關的圖形。 WPF 圖形系統的基本度量單位是與設備無關的像素,它等於一英寸的 1/96,而無論實際的屏幕分辨率是多少,爲與分辨率和設備無關的呈現提供了基礎。 每一個與設備無關的像素都會自動縮放,以符合呈現該像素的系統上的每英寸點數 (dpi) 設置。
-
更高的精度。 WPF 座標系是使用雙精度浮點數字測量的,而不是使用單精度浮點數字。 轉換值和不透明度值也以雙精度表示。 WPF 還支持普遍的顏色域 (scRGB),併爲管理來自不一樣顏色空間的輸入提供了完整的支持。
-
高級圖形和動畫支持。 WPF 經過爲您管理動畫場景簡化了圖形編程;您不須要擔憂場景處理、呈現循環和雙線性內插算法。 此外,WPF 還提供了命中測試支持和全面的 alpha 合成支持。
-
硬件加速。 WPF 圖形系統利用了圖形硬件的優點來最小化 CPU 使用率。
二維形狀
WPF 提供了一個庫,包含用矢量繪製的通用二維形狀,以下圖中演示的矩形和橢圓。
![橢圓和矩形 橢圓和矩形](http://static.javashuo.com/static/loading.gif)
形狀具備一個有趣的功能:它們不只僅用於顯示,還實現了您能夠從控件中得到的許多功能,包括鍵盤和鼠標輸入。 下面的示例演示正在處理的 Ellipse 的 MouseUp 事件。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.EllipseEventHandlingWindow" Title="Click the Ellipse"> <Ellipse Name="clickableEllipse" Fill="Blue" MouseUp="clickableEllipse_MouseUp" /> </Window>
Imports System.Windows ' Window, MessageBox Imports System.Windows.Input ' MouseButtonEventArgs Namespace SDKSample Public Class EllipseEventHandlingWindow Inherits Window Public Sub New() InitializeComponent() End Sub Private Sub clickableEllipse_MouseUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs) MessageBox.Show("You clicked the ellipse!") End Sub End Class End Namespace
using System.Windows; // Window, MessageBox using System.Windows.Input; // MouseButtonEventHandler namespace SDKSample { public partial class EllipseEventHandlingWindow : Window { public EllipseEventHandlingWindow() { InitializeComponent(); } void clickableEllipse_MouseUp(object sender, MouseButtonEventArgs e) { // Display a message MessageBox.Show("You clicked the ellipse!"); } } }
下圖演示了以上代碼生成的結果。
![包含文本「單擊省略號!」的窗口 包含文本「單擊省略號!」的窗口](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見 WPF 中的形狀和基本繪圖概述。 有關介紹性示例,請參見 Shape Elements Sample(形狀元素示例)。
二維幾何圖形
WPF 提供的二維形狀涵蓋了基本形狀的標準集合。 可是,您可能須要建立自定義形狀以幫助設計自定義的 UI。 出於此目的,WPF 提供了幾何圖形。 下圖演示了使用幾何圖形建立一個能夠直接繪製、用做畫筆或用於剪裁其餘形狀和控件的自定義形狀。
Path 對象可用於繪製閉合或開放形狀、多線形狀,甚至曲線形狀。
Geometry 對象可用於對二維圖形數據進行剪裁、命中測試和呈現。
![Path 的各類用法 Path 的各類用法](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見Geometry 概述。 有關介紹性示例,請參見 Geometries Sample(幾何圖形示例)。
二維效果
WPF 二維功能的子集包括漸變、位圖、繪圖、視頻繪製、旋轉、縮放和扭曲等視覺效果。 這些均可以使用畫筆完成;下圖演示了某些示例。
![不一樣畫筆的圖示 不一樣畫筆的圖示](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見 WPF 畫筆概述。 有關介紹性示例,請參見 Brushes Sample(畫筆示例)。
三維呈現
WPF 還包括三維呈現功能,這些功能能夠與二維圖形進行集成,以便於建立更激動人心、更有趣的 UI。 例如,下圖演示了呈如今三維形狀上的二維圖像。
![Visual3D 示例屏幕快照 Visual3D 示例屏幕快照](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見三維圖形概述。 有關介紹性示例,請參見 3-D Solids Sample(三維實體示例)。
WPF 動畫支持可使控件變大、旋轉、調節和淡化,以產生有趣的頁面過渡和更多效果。 您能夠對大多數 WPF 類(甚至自定義類)進行動畫處理。 下圖演示了一個簡單的活動動畫。
![具備動畫效果的立方體圖 具備動畫效果的立方體圖](http://static.javashuo.com/static/loading.gif)
請參見動畫概述。 Animation Example Gallery(動畫示例庫)。
傳達豐富內容的一個方法是使用視聽媒體。 WPF 爲圖像、視頻和音頻提供了特殊的支持。
圖像
圖像對大多數應用程序來講都很常見,WPF 提供了幾種方式來使用圖像。 下圖演示了具備一個列表框的 UI,該列表框中包含縮略圖圖像。 當選中一個縮略圖時,該圖像將以完整大小顯示。
參見圖像處理概述。
視頻和音頻
MediaElement 控件既能夠播放視頻,也能夠播放音頻,它的靈活程度使其足以用做自定義媒體播放器的基礎。 下面的 XAML 標記實現一個媒體播放器。
下圖中的窗口演示 MediaElement 活動控件。
![具備音頻和視頻的 MediaElement 控件 具備音頻和視頻的 MediaElement 控件](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見 圖形和多媒體。
爲了加快高質量的文本呈現,WPF 提供瞭如下功能:
-
OpenType 字體支持。
-
ClearType 加強。
-
利用硬件加速優點的高性能。
-
文本與媒體、圖形和動畫的集成。
-
國際字體支持和回退機制。
爲了說明文本與圖形的集成,下圖演示了文本效果的應用。
![具備各類文本修飾的文本 具備各類文本修飾的文本](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見 WPF 中的版式。
WPF 自己支持使用三種類型的文檔:流文檔、固定文檔和 XML 紙張規範 (XPS) 文檔。 WPF 還提供了用於建立、查看、管理、批註、打包和打印文檔的服務。
流文檔
流文檔的設計用途是,當窗口大小和顯示設置發生變化時,經過動態調整和迴流內容來優化查看和可讀性。 下面的 XAML 標記演示了FlowDocument的定義。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <Paragraph FontSize="18" FontWeight="Bold">Flow Document</Paragraph> <Paragraph> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure. </Paragraph> ... </FlowDocument>
下面的示例演示如何將流文檔加載到 FlowDocumentReader 中以進行查看、搜索和打印。
Imports System.Windows 'Window Imports System.Windows.Documents 'FlowDocument Imports System.IO 'FileStream, FileMode Imports System.Windows.Markup 'XamlReader Namespace SDKSample Public Class FlowDocumentReaderWindow Inherits Window Public Sub New() Me.InitializeComponent() Using stream1 As FileStream = New FileStream("AFlowDocument.xaml", _ FileMode.Open, FileAccess.Read) Dim document1 As FlowDocument = _ TryCast(XamlReader.Load(stream1), FlowDocument) Me.flowDocumentReader.Document = document1 End Using End Sub End Class End Namespace
using System.Windows; // Window using System.Windows.Documents; // FlowDocument using System.IO; // FileStream, FileMode using System.Windows.Markup; // XamlReader namespace SDKSample { public partial class FlowDocumentReaderWindow : System.Windows.Window { public FlowDocumentReaderWindow() { InitializeComponent(); // Open the file that contains the FlowDocument using (FileStream xamlFile = new FileStream("AFlowDocument.xaml", FileMode.Open, FileAccess.Read)) { // Parse the file with the XamlReader.Load method FlowDocument content = XamlReader.Load(xamlFile) as FlowDocument; // Set the Document property to the parsed FlowDocument object this.flowDocumentReader.Document = content; } } } }
下面的示例演示告終果。
![FlowDocumentReader 控件中的 FlowDocument FlowDocumentReader 控件中的 FlowDocument](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見流文檔概述。
固定文檔
固定文檔適用於須要精確的「所見即所得」(WYSIWYG) 演示的應用程序,尤爲是對於打印。 固定文檔的典型用途包括桌面發佈、字處理和窗體佈局,在這些狀況下,遵循原始頁面設計很是關鍵。
固定文檔經過與設備無關的方式維護了文檔內容的精確排列。 例如,一個固定文檔在 96 dpi 顯示器上顯示的效果與在 600 dpi 激光打印機或 4800 dpi 照相排字機上打印的效果是同樣的。 雖然文檔的質量會因每臺設備的功能不一樣而有所不一樣,可是佈局在全部狀況下都保持不變。
有關更多信息,請參見 WPF 中的文檔。
XPS 文檔
XML 紙張規範 (XPS) 文檔創建在 WPF 的固定文檔基礎上。 XPS 文檔使用基於 XML 的架構進行描述,該架構本質上就是電子文件的分頁表示。 XPS 是一個開放的、跨平臺的文檔格式,旨在簡化分頁文檔的建立、共享、打印和存檔。 XPS 技術的重要功能包括:
-
將 XPS 文檔打包爲符合 Open Packaging Conventions(開放打包約定,OPC)的 ZipPackage 文件。
-
由獨立應用程序和基於瀏覽器的應用程序承載。
-
從 WPF 應用程序中手動生成和操做 XPS 文檔。
-
經過追求最大化輸出設備質量進行高保真呈現。
-
Windows Vista 後臺打印。
-
將文檔直接傳送到與 XPS 兼容的打印機。
-
UI 與 DocumentViewer 集成。
下圖演示由 DocumentViewer 顯示的 XPS 文檔。
![DocumentViewer 控件內的 XPS 文檔 DocumentViewer 控件內的 XPS 文檔](http://static.javashuo.com/static/loading.gif)
DocumentViewer 還容許用戶更改視圖、搜索和打印 XPS 文檔。
有關更多信息,請參見 WPF 中的文檔。
批註
批註是在文檔中添加的說明或註釋,用於標記信息或突出顯示相關項目,以便於之後參考。 儘管在打印文檔上編寫說明很容易,但在電子文檔上「編寫」說明的功能經常受到限制或者不可用。 可是,WPF 中提供了一個批註系統,以支持粘滯便筏和突出顯示。 此外,這些批註還可應用於 DocumentViewer 控件中承載的文檔,以下圖所示。
![批註樣式 批註樣式](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見批註概述。
打包
WPF System.IO.Packaging API 容許您的應用程序將數據、內容和資源組織成一個可移植、易於分發和訪問的 ZIP 文檔。 能夠包括數字簽名以對程序包中包含的項目進行身份驗證,並肯定簽名的項目未被篡改或修改。 您還可使用權限管理對軟件包進行加密,以限制對受保護信息的訪問。
有關更多信息,請參見 WPF 中的文檔。
打印
.NET Framework 包括一個打印子系統,WPF 經過支持更好的打印系統控制對其進行了加強。 打印加強功能包括:
-
實時安裝遠程打印服務器和隊列。
-
動態發現打印機功能。
-
動態設置打印機選項。
-
打印做業從新路由和從新排列優先級別次序。
XPS 文檔還包含一個關鍵的性能改進功能。 現有的 Microsoft Windows 圖形設備接口 (GDI) 打印路徑一般須要兩次轉換:
-
第一次是將文檔轉換成打印處理器格式,如加強型圖元文件 (EMF)。
-
第二次是轉換成打印機的頁面描述語言,如打印機控制語言 (PCL) 或 PostScript。
可是,XPS 文檔避免了這些轉換,由於 XPS 文件格式的一個組件是打印處理器語言和頁面描述語言。 這項支持有助於減小打印後臺文件的大小和網絡打印機的負載。
有關更多信息,請參見打印概述。
到目前爲止,您已經看到了開發應用程序的核心 WPF 生成塊。 您可使用應用程序模型承載和提供主要由控件構成的應用程序內容。 若要簡化 UI 中的控件排列,並確保在窗口大小和顯示設置更改時維護這種排列,請使用 WPF 佈局系統。 因爲大多數應用程序都容許用戶與數據交互,所以您可使用數據綁定減小將 UI 與數據相集成的工做量。若要改進應用程序的視覺外觀,請使用 WPF 提供的各類圖形、動畫和媒體支持。 最後,若是您的應用程序經過文本和文檔進行操做,您可使用 WPF 文本、版式、文檔、批註、打包和打印功能。
儘管如此,基本功能一般不足以建立和管理真正不同凡響、具備視覺震撼力的用戶體驗。 標準 WPF 控件可能不能與所需的應用程序外觀集成。 數據可能不能以最有效的方式顯示。 應用程序的總體用戶體驗可能不適合 Windows 主題的默認外觀。 在不少方面,演示技術須要具備像其餘任何擴展性那樣多的視覺擴展性。
出於這個緣由,WPF 爲建立獨特的用戶體驗提供了各類機制,包括一個內容豐富的模型,用於控件、觸發器、控件和數據模板、樣式、UI 資源以及主題和外觀。
內容模型
大多數 WPF 控件的主要目的都是爲了顯示內容。 在 WPF 中,構成控件內容的項目類型和數量被稱爲控件的「內容模型」。 有些控件只能包含一個項目和內容類型;例如,TextBox 的內容爲字符串值,該值被分配給 Text 屬性。 下面的示例設置 TextBox 的內容。
下圖演示告終果。
![包含文本的 TextBox 控件 包含文本的 TextBox 控件](http://static.javashuo.com/static/loading.gif)
可是,其餘控件能夠包含多個具備不一樣內容類型的項目;Button 的內容(由 Content 屬性指定)能夠包含各類項目,包括佈局控件、文本、圖像和形狀。 下面的示例演示 Button,其內容包括 DockPanel、Label、Border 和 MediaElement。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.ButtonContentWindow" Title="Button Content"> ... <Button Margin="20"> <!-- Button Content --> <DockPanel Width="200" Height="180"> <Label DockPanel.Dock="Top" HorizontalAlignment="Center">Click Me!</Label> <Border Background="Black" BorderBrush="Yellow" BorderThickness="2" CornerRadius="2" Margin="5"> <MediaElement Source="media/wpf.wmv" Stretch="Fill" /> </Border> </DockPanel> </Button> ... </Window>
下圖演示了此按鈕的內容。
![包含多種類型的內容的按鈕 包含多種類型的內容的按鈕](http://static.javashuo.com/static/loading.gif)
有關各類控件支持的內容類型的更多信息,請參見 WPF 內容模型。
觸發器
儘管 XAML 標記的主要目的是實現應用程序的外觀,但您也可使用 XAML 實現應用程序行爲的某些方面。 一個示例就是使用觸發器根據用戶交互更改應用程序的外觀。 有關更多信息,請參見樣式設置和模板化中的「觸發器」。
控件模板
WPF 控件的默認 UI 一般由其餘控件和形狀構造而來。 例如,一個 Button 由 ButtonChrome 和 ContentPresenter 控件組成。 ButtonChrome 提供標準按鈕外觀,而 ContentPresenter 顯示按鈕的內容(由 Content 屬性指定)。
有時控件的默認外觀可能與應用程序的總體外觀不一致。 在這種狀況下,您可使用 ControlTemplate 更改控件的 UI 的外觀,而無需更改控件的內容和行爲。
例如,下面的示例演示如何使用 ControlTemplate 更改 Button 的外觀。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.ControlTemplateButtonWindow" Title="Button with Control Template" Height="158" Width="290"> <!-- Button using an ellipse --> <Button Content="Click Me!" Click="button_Click"> <Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <Grid Margin="5"> <Ellipse Stroke="DarkBlue" StrokeThickness="2"> <Ellipse.Fill> <RadialGradientBrush Center="0.3,0.2" RadiusX="0.5" RadiusY="0.5"> <GradientStop Color="Azure" Offset="0.1" /> <GradientStop Color="CornflowerBlue" Offset="1.1" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> <ContentPresenter Name="content" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </ControlTemplate> </Button.Template> </Button> </Window>
Imports System.Windows ' Window, RoutedEventArgs, MessageBox Namespace SDKSample Public Class ControlTemplateButtonWindow Inherits Window Public Sub New() InitializeComponent() End Sub Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) MessageBox.Show("Hello, Windows Presentation Foundation!") End Sub End Class End Namespace
using System.Windows; // Window, RoutedEventArgs, MessageBox namespace SDKSample { public partial class ControlTemplateButtonWindow : Window { public ControlTemplateButtonWindow() { InitializeComponent(); } void button_Click(object sender, RoutedEventArgs e) { // Show message box when button is clicked MessageBox.Show("Hello, Windows Presentation Foundation!"); } } }
在此示例中,默認按鈕 UI 被替換爲 Ellipse,後者具備深藍色的邊框並使用 RadialGradientBrush 進行填充。 ContentPresenter 控件顯示 Button 的內容,即「Click Me!」。單擊 Button 時,仍會做爲 Button 控件的部分默認行爲引起 Click 事件。 下圖演示告終果。
![省略號按鈕和第二個窗口 省略號按鈕和第二個窗口](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見 ControlTemplate。 有關介紹性示例,請參見 Styling with ControlTemplates Sample(使用 ControlTemplates 設置樣式的示例)。
數據模板
控件模板使您能夠指定控件的外觀,數據模板則容許您指定控件內容的外觀。 數據模板一般用於改進綁定數據的顯示方式。 下圖演示 ListBox 的默認外觀,它被綁定到一個 Task 對象集合,該集合中的每一個任務都有一個名稱、說明和優先級別。
![具備默認外觀的列表框 具備默認外觀的列表框](http://static.javashuo.com/static/loading.gif)
默認外觀是您但願 ListBox 具備的外觀。 可是,每一個任務的默認外觀只包含任務名稱。 若要顯示任務名稱、說明和優先級別,必須使用 DataTemplate 更改 ListBox 控件的綁定列表項的默認外觀。 下面的 XAML 定義了這樣一個 DataTemplate,它經過使用 ItemTemplate 特性應用於每一個任務。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.DataTemplateWindow" Title="With a Data Template"> ... <Window.Resources> <!-- Data Template (applied to each bound task item in the task collection) --> <DataTemplate x:Key="myTaskTemplate"> <Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2" CornerRadius="2" Padding="5" Margin="5"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="Task Name:"/> <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=TaskName}"/> <TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="Description:"/> <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/> <TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/> <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/> </Grid> </Border> </DataTemplate> </Window.Resources> ... <!-- UI --> <DockPanel> <!-- Title --> <Label DockPanel.Dock="Top" FontSize="18" Margin="5" Content="My Task List:"/> <!-- Data template is specified by the ItemTemplate attribute --> <ListBox ItemsSource="{Binding}" ItemTemplate="{StaticResource myTaskTemplate}" HorizontalContentAlignment="Stretch" IsSynchronizedWithCurrentItem="True" Margin="5,0,5,5" /> </DockPanel> ... </Window>
下圖演示了此代碼的效果。
![使用數據模板的列表框 使用數據模板的列表框](http://static.javashuo.com/static/loading.gif)
請注意,ListBox 保留其行爲和總體外觀;只有列表框顯示的內容的外觀發生了變化。
有關更多信息,請參見數據模板化概述。 有關介紹性示例,請參見 Introduction to Data Templating Sample(數據模板化簡介示例)。
樣式
開發人員和設計人員使用樣式能夠對其產品的特定外觀進行標準化處理。 WPF 提供了一個強大的樣式模型,其基礎是 Style 元素。 下面的示例建立一個樣式,該樣式將窗口中的每一個 Button 的背景色設置爲 Orange。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.StyleWindow" Title="Styles"> ... <!-- Style that will be applied to all buttons --> <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="Orange" /> <Setter Property="BorderBrush" Value="Crimson" /> <Setter Property="FontSize" Value="20" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="Margin" Value="5" /> </Style> ... <!-- This button will have the style applied to it --> <Button>Click Me!</Button> <!-- This label will not have the style applied to it --> <Label>Don't Click Me!</Label> <!-- This button will have the style applied to it --> <Button>Click Me!</Button> ... </Window>
因爲此樣式針對全部 Button 控件,所以它自動應用於窗口中的全部按鈕,以下圖所示。
![兩個橙色按鈕 兩個橙色按鈕](http://static.javashuo.com/static/loading.gif)
有關更多信息,請參見樣式設置和模板化。 有關介紹性示例,請參見 Introduction to Styling and Templating Sample(樣式設置和模板化示例簡介)。
資源
一個應用程序中的各控件應共享相同的外觀,包括從字體和背景色到控件模板、數據模板和樣式的全部方面。 您可使用 WPF 對用戶界面 (UI) 資源的支持將這些資源封裝到一個位置,以便於重複使用。
下面的示例定義一個通用的由 Button 和 Label 共享的背景色。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.ResourcesWindow" Title="Resources Window"> <!-- Define window-scoped background color resource --> <Window.Resources> <SolidColorBrush x:Key="defaultBackground" Color="Red" /> </Window.Resources> ... <!-- Button background is defined by window-scoped resource --> <Button Background="{StaticResource defaultBackground}">One Button</Button> <!-- Label background is defined by window-scoped resource --> <Label Background="{StaticResource defaultBackground}">One Label</Label> ... </Window>
此示例使用 Window.Resources 屬性元素實現背景色資源。 此資源可用於 Window 的全部子項。 資源範圍有多種,包括下面按解析順序列出的範圍:
-
單個控件(使用繼承的 FrameworkElement.Resources 屬性)。
-
Window 或 Page(也使用繼承的 FrameworkElement.Resources 屬性)。
-
Application (使用 Application.Resources 屬性)。
範圍的多樣性使您能夠靈活選擇定義和共享資源的方式。
做爲將資源與特定範圍直接關聯的一個備用方法,您可使用單獨的 ResourceDictionary(能夠在應用程序的其餘部分引用)打包一個或多個資源。 例如,下面的示例在資源字典中定義默認背景色。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- Define background color resource --> <SolidColorBrush x:Key="defaultBackground" Color="Red" /> <!-- Define other resources --> ... </ResourceDictionary>
下面的示例引用上一個示例中定義的資源字典,從而在應用程序中共享。
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.App"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="BackgroundColorResources.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> ... </Application>
資源和資源字典是 WPF 支持主題和外觀的基礎。
參見XAML 資源。
主題和外觀
從視覺的角度上講,主題定義 Windows 以及在其中運行的應用程序的全局外觀。 Windows 附帶了幾個主題。 例如,Microsoft Windows XP 附帶了 Windows XP 和 Windows 經典主題,而 Windows Vista 附帶了 Windows Vista 和 Windows 經典主題。 由主題定義的外觀可定義 WPF 應用程序的默認外觀。 可是,WPF 並未與 Windows 主題直接集成。因爲 WPF 的外觀由模板定義,所以 WPF 爲每一個已知 Windows 主題包括了一個模板,這些主題包括 Aero (Windows Vista)、Classic (Microsoft Windows 2000)、Luna (Microsoft Windows XP) 和 Royale (Microsoft Windows XP Media Center Edition 2005)。這些主題做爲資源字典進行打包,若是未在應用程序中找到資源,則能夠解析這些資源字典。許多應用程序依賴於這些主題來定義其視覺外觀;與 Windows 外觀保持一致有助於用戶更輕鬆地熟悉更多應用程序。
另外一方面,某些應用程序的用戶體驗不必定來自標準主題。 例如,Microsoft Windows Media Player 經過音頻和視頻數據進行操做,並受益於不一樣風格的用戶體驗。 此類 UI 能夠提供自定義的、應用程序特定的主題。 這些主題稱爲外觀,帶有外觀的應用程序一般提供掛鉤,用戶能夠經過這些掛鉤自定義外觀的各個方面。Microsoft Windows Media Player 具備多個預製的外觀以及大量第三方外觀。
WPF 中的主題和外觀均可以使用資源字典很是輕鬆地進行定義。 下面的示例演示示例外觀定義。
<!-- Blue Skin --> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SDKSample"> <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="Blue" /> </Style> ... </ResourceDictionary>
<!-- Yellow Skin --> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SDKSample"> <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="Yellow" /> </Style> ... </ResourceDictionary>
有關更多信息,請參見樣式設置和模板化中的「共享的資源和主題」。
自定義控件
儘管 WPF 提供了大量自定義項支持,您仍然可能會遇到現有 WPF 控件不能知足應用程序或用戶需求的狀況。 在如下狀況下可能會出現這種情形:
-
沒法經過自定義現有 WPF 實現的外觀來建立您須要的 UI。
-
現有 WPF 實現不支持(或很難支持)您須要的行爲。
可是,目前您能夠利用三個 WPF 模型之一建立一個新的控件。 每一個模型都針對一個特定的方案,並要求您的自定義控件從特定的 WPF 基類派生而來。 此處列出了此三個模型:
-
用戶控件模型。 從 UserControl 派生的自定義控件,由其餘一個或多個控件組成。
-
控制模型。 從 Control 派生的自定義控件,用於生成使用模板將其行爲和外觀相分離的實現,與多數 WPF 控件很是類似。 從 Control 派生,與用戶控件相比,您能夠更自由地建立自定義 UI,但可能須要投入更多精力。
-
框架元素模型。 從 FrameworkElement 派生的自定義控件,其外觀由自定義呈現邏輯(而不是模板)定義。
下面的示例演示從 UserControl 派生的自定義數值 up/down 控件。
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.NumericUpDown"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <!-- Value text box --> <Border BorderThickness="1" BorderBrush="Gray" Margin="2" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Stretch"> <TextBlock Name="valueText" Width="60" TextAlignment="Right" Padding="5"/> </Border> <!-- Up/Down buttons --> <RepeatButton Name="upButton" Click="upButton_Click" Grid.Column="1" Grid.Row="0">Up</RepeatButton> <RepeatButton Name="downButton" Click="downButton_Click" Grid.Column="1" Grid.Row="1">Down</RepeatButton> </Grid> </UserControl>
imports System 'EventArgs imports System.Windows 'DependencyObject, DependencyPropertyChangedEventArgs, ' FrameworkPropertyMetadata, PropertyChangedCallback, ' RoutedPropertyChangedEventArgs imports System.Windows.Controls 'UserControl Namespace SDKSample ' Interaction logic for NumericUpDown.xaml Partial Public Class NumericUpDown Inherits System.Windows.Controls.UserControl 'NumericUpDown user control implementation ... End Class End Namespace
using System; // EventArgs using System.Windows; // DependencyObject, DependencyPropertyChangedEventArgs, // FrameworkPropertyMetadata, PropertyChangedCallback, // RoutedPropertyChangedEventArgs using System.Windows.Controls; // UserControl namespace SDKSample { public partial class NumericUpDown : UserControl { // NumericUpDown user control implementation ... } }
下一個示例演示將用戶控件與 Window 合併所需的 XAML。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SDKSample.UserControlWindow" xmlns:local="clr-namespace:SDKSample" Title="User Control Window"> ... <!-- Numeric Up/Down user control --> <local:NumericUpDown /> ... </Window>
下圖演示 Window 中承載的 NumericUpDown 控件。
![自定義 UserControl 自定義 UserControl](http://static.javashuo.com/static/loading.gif)
有關自定義控件的更多信息,請參見控件創做概述。
本文中提到了如下概述和示例。
概述
示例
3-D Solids Sample(三維實體示例) Animation Example Gallery(動畫示例庫) Brushes Sample(畫筆示例) Data Binding Demo(數據綁定演示) Geometries Sample(幾何圖形示例) |
Introduction to Data Templating Sample(數據模板化簡介示例) Introduction to Styling and Templating Sample(樣式和模板化簡介示例) Shape Elements Sample(Shape 元素示例) Styling with ControlTemplates Sample(使用 ControlTemplates 設置樣式的示例) WPF Layout Gallery Sample(WPF 佈局庫示例) |