第0問:能否簡單介紹一下本文的結構?
本文解答了關於WPF的9個最常見的問題。從某種意義上講,這兩種技術是相互關聯的:它們都是關於界面表現的技術,更進一步的,Silverlight是基於WPF的,是它的一個子集。不僅從理論上介紹了這兩種技術,同時還提供了一些小的例子供大家參考。
第1問:我們已經有了GDI、GDI+和DirectX,爲什麼我們還需要WPF呢?
圖1 從User32到WPF的發展歷程
首先,讓我們來回顧一下微軟的各種界面顯示技術:
User32:它提供了最基本的Windows界面,包括按鈕,編輯框和其他UI元素。但是,User32缺乏的是圖形圖像的繪製功能,無法對屏幕實現自定義的繪製。
GDI (Graphics device interface):- 爲了提供圖形圖像的繪製功能,微軟在User32的基礎上引入了GDI。GDI不僅提供了圖形圖像的繪製功能,同時還對硬件顯示進行了更高層次的抽象。換句話說,它將硬件的複雜性封裝在了GDI API中,用戶使用起來更加方便。
GDI+:顧名思義,GDI+是作爲GDI的擴展而被引入到Windows中的。它提供了很多GDI所沒有的擴展功能,例如對JPG和PNG圖像格式支持,漸變陰影和抗鋸齒等。無論是GDI還是GDI+,它們最大的侷限就是不支持硬件加速,同時無法展現動畫和3D圖像。
提示:所謂硬件加速,就是使用硬件來執行某些功能,以替代使用軟件在CPU中執行的某些功能,因爲直接使用硬件,這樣可以顯著地加快圖形圖像處理的速度。
DirectX :正如我們在上面所分析的那樣,GDI及其擴展GDI+的一個最大問題就是不支持硬件加速和動畫。這對於遊戲開發者來說,是無法接受的。爲了解決這個問題,微軟開發了DirectX。DirectX能夠很好的利用硬件加速,能夠支持3D,全綵圖像,流媒體等等,非常適合遊戲工業等對圖形圖像處理要求比較高的領域。
WPF:微軟已經有了這麼多套關於顯示技術的API,爲什麼還要多此一舉,創建另外一套顯示技術的API呢?通過對硬件加速的支持,DirectX已經有了很多非常棒的特性。微軟想利用支持硬件加速的DirectX技術來開發UI元素,比如文本框,按鈕,網格等等,所以他們又在DirectX的基礎上開發了WPF。因爲WPF是在DirectX的基礎上實現的,所以你不僅可以利用WPF創建簡單的UI元素,還可以更進一步,開發特殊的UI元素,例如網格(Grid),流文檔(FlowDocument)和橢圓(Ellipse)等。
更進一步地,你還可以利用WPF創建動畫。如果你在尋找用於創建輕量級動畫(不是遊戲中所使用的那種複雜三維動畫)的技術方案,WPF將是一個不錯的選擇。你可以使用被稱爲XAML的XML文件來表現WPF。
圖2 WPF和DirectX的關係
簡單的講,WPF就是DirectX之上的一層包裝。所以,我們可以這樣定義WPF:
WPF是一套用於簡便地構建動態用戶界面的類的集合。這些類包括了一套新的界面控件。其中有些控件跟舊有的UI元素是相似的,例如標籤,文本框和按鈕等,而另外一些控件則是全新的,例如,網格(Grid),流文檔(FlowDocument)和橢圓(Ellipse)等。
第2問:WPF中的硬件加速是如何工作的?
正如我們在前文所介紹的那樣,簡而言之,硬件加速就是利用硬件來替代軟件算法以充分利用硬件所固有的快速運算的特性。
WPF從以下三個層次上來利用硬件加速的特性:
圖3 WPF硬件加速的三個層次
WPF API首先檢測你的硬件系統所支持的硬件加速的等級,比如顯卡的顯存大小,像素深度等等。基於你所使用的硬件,WPF將從以下三種渲染模式中的選擇一種作爲其渲染模式:
第0級
如果你的顯卡不支持硬件加速,WPF將採用第0級渲染模式。也就是說它將使用軟件加速。這相當於使用低於7.0版本的DirectX。
第1級
如果你的顯卡部分地支持硬件加速,那麼WPF將採用第1級渲染模式。這相當於使用版本號在7.0到9.0之間的DirectX。
第2級
如果你的顯卡完全支持硬件加速,那麼WPF將採用第2級渲染模式。這相當於使用版本號等於或者大於9.0的DirectX。
第3問:這是否意味着WPF將取代DirectX?
不,WPF並不會取代DirectX。DirectX將繼續用於創建頂級的三維遊戲。DirectX的視頻性能在很多時候還是高於WPF API的。當用於遊戲開發的時候,從性能的角度考慮,我們總是會選擇DirectX,而不是WPF。WPF並不是設計遊戲的最佳方案,當然,你可以用WPF來實現一個簡單的俄羅斯方塊遊戲,但是對於一些需要很多動畫的三維遊戲,WPF就顯得力不從心了。
我們只需要記住一點:WPF是Windows窗體的替代者,而不是DirectX的掘墓人。
第4問:那麼,如何更加準確地定義WPF呢?
WPF(Windows Presentation Framework)是一套全新的用於Windows 的顯示子系統。WPF擁有一個二維和三維圖形引擎。它擁有以下這些特性:
Windows界面
WPF支持所有通用的Windows控件,例如按鈕,複選框,滑動條等等。無論其界面使用哪種樣式,WPF 應用程序都可以通過面板進行基本佈局。一個面板通常包含多個控件,這些由 WPF 提供的控件包括按鈕、文本框、組合框、菜單以及其他對象。這些控件如何放置取決於你所選擇的面板類型。例如,網格(Grid) 允許將控件放在指定的網格上,而 畫布(Canvas) 則允許開發人員將控件放在其界限範圍內的任何位置。在 GUI 中,通常用戶觸發的事件由應用程序中的不同控件和其他類進行捕獲和處理。在WPF中,我們還可以將樣式和模板應用到控件組,這樣就可以非常容易使應用程序具有一致的外觀。
對文檔的支持
WPF 應用程序可以使用 XAML 的 FixedDocument 標記來顯示 XPS 文檔。也可以使用 FlowDocument 標記來顯示流文檔。流文檔與傳統的屏幕文檔類似,能夠讓用戶滾動瀏覽其內容。另外,開發人員通過設置此標記的不同屬性,可以使文檔更適應其環境。例如,文 檔可以每次顯示一頁,這樣讀者就不必上下滾動頁面了。WPF 還能夠根據顯示文檔的窗口大小來自動確定應該把文檔拆分成多少列。其目的是儘量提高屏幕上文檔的可讀性。
對圖形的支持
WPF 還支持創建二維和三維矢量圖形。對於二維圖形,WPF 可提供標準抽象,例如形狀、畫筆和繪圖筆,同時還允許三維圖形定義模型,以用於指定光線和攝像機位置信息。與早期技術(例如 Windows Forms 需要依賴於 GDI+ 才能繪製圖形)不同的是,WPF 圖形並不是使用開發人員所必須瞭解的單獨一組概念來進行分區的。相反,用於圖形的 XAML 元素能夠與那些用戶界面其他方面的元素自然組合。按鈕可帶有圖形內容,文本和圖形可以組合等。
對圖像的支持
使用 XAML 的圖像標記,WPF 應用程序可以顯示不同格式的圖形,包括 JPEG、GIF 以及其他格式。WPF 依靠 Windows Imaging Component (WIC) 爲編解碼器以及顯示和存儲圖像的軟件提供標準框架。在WPF中,通常圖像元素可以與其他元素組合,能夠讓按鈕顯示圖像而不是簡單的文本標籤。
動畫
WPF 提供動態顯示絕大部分用戶界面的內置支持。例如,放大和縮小圓圈、平滑地更改按鈕大小。應用程序還可以定義包含時間線的情節提要,允許調整動畫的發生順序。
多媒體
WPF 應用程序可以使用 MediaElement 標記來顯示不同格式的視頻和音頻,包括 WMV、AVI 和 MPEG。同樣,此元素也可與其他 XAML 元素相組合,例如使三維立方體的所有側面上都顯示視頻。
·數據綁定
由於許多 WPF 應用程序都需要顯示數據,因此提供將數據映射到用戶界面元素的自動支持功能是很有幫助的。WPF 可爲包含在對象和其他源中的信息提供此類數據綁定。WPF 數據綁定還允許在顯示數據前對其進行排序和篩選。
第5問:什麼是XAML?
XAML(讀作Zammel)是eXtensible Application Markup Language的英文縮寫,它是一門基於XML的描述性語言。利用XAML,你可以用XML定義對象或者屬性。在處理的時候,XAML文檔首先被一個XAML解析器加載,然後解析器會創建相應的對象實例並設置他們的屬性。XAML描述了對象,屬性和他們之間的關係。使用XAML,你可以創建各種對象,不管他們是圖形的還是非圖形的。WPF會負責解析XAML文檔並根據文檔中說定義的內容創建相應的對象實例,同時根據XAML中的描述創建他們之間的關係。
所以,XAML是一個定義了對象和屬性的XML文檔。並且WPF會加載這個文檔到當前內存空間以創建這些對象以及他們之間的關係。
第6問:XAML只是針對WPF的嗎?
不是的,XAML並不只是針對WPF而設計的。XAML是一門基於XML的標記語言並且它有多個變種:
WPF XAML用於描述WPF相關的內容,比如WPF對象、控件和文檔等。在WPF XAML中我們還有XPS XAML,它可以用於定義一個電子文檔的XML表現形式。
Silverlight XAML是WPF XAML的一個子集,專門用於Silverlight應用程序。Silverlight是一個跨平臺的瀏覽器插件。利用Silverlight,我們可以創建豐富多彩的Web內容,包括二維圖形,動畫,音頻和視頻等。
WWF XAML用於描述Windows Workflow Foundation(WWF)的內容。WWF引擎會加載XAML文檔並按照其中的描述調用工作流。
第7問:能解釋一下WPF的總體架構嗎?
圖4 WPF的總體架構
上圖展示了WPF的總體架構。WPF主要由三個部分構成:表現核心(Presentation Core)、表現框架(Presentation Framework)和媒體集成庫(MilCore)。在圖中,我們還可以看到WPF體系結構中的其他部分,例如DirectX在整個體系中的位置,操作系統與整個WPF系統的交互等等。下面讓我們來看看WPF中各個部分都是如何工作的:
User32:負責確定顯示窗口及其在屏幕中的位置狀態等,其並不參與常見控件的呈現。DirectX: - 如前所述,WPF在本質上是使用DirectX的。DirectX負責跟硬件驅動通信並顯示窗口和窗口內容。
Milcore:Mil是媒體集成庫(Media Integration Library)的簡稱。這部分是非託管代碼,因爲它就像一座橋樑,負責託管的WPF和非託管的DirectX/User32 API之間的通信。
Presentation core :這是WPF所公佈出來的底層API。主要包括WPF的一些基本類型,例如UIElement,2D元素,3D元素,幾何元素等。它們是Presentation Framework所包括元素的基礎。
Presentation framework:- 這是WPF所公佈出來的高層API。它主要包括WPF的窗口、面板、樣式,佈局等高層WPF類型,通過這些內容,我們可以構建豐富的應用程序界面。
第8問:WPF中的名字空間和類層次是怎麼樣的?
圖5 WPF的名字空間和類層次
在WPF中,有10個比較重要的名字空間和類:
System.Threading.DispatcherObject
所有的WPF對象都派生自DispatcherObject。我們知道WPF工作在Single Threading Apartment(STA)模型下,DispatcherObject的主要職責就是處理線程的併發和同步。當有消息發生的時候,比如鼠標點擊或者是按鈕被按下,這些消息將被髮送到DispatcherObject,它將負責驗證代碼是否運行在當前線程。在接下來的章節中,我們將詳細介紹WPF的線程是如何工作的。
System.Windows.DependencyObject
微軟在設計WPF的時候,考慮的是一種基於屬性的架構。換句話說,對象的行爲主要是用屬性來表現的,而不是方法,函數和事件。現在,我們只需要記住它的定義就可以了。在下面的章節中,我們將有專門的問題來論述這個主題。
System.Windows.Media.Visual
Visual是一個顯示支持類,用於抽象所有關於繪製顯示的描述。它是一個抽象類,每個Framework Element對象都必須繼承該類。該類的主要作用是爲WPF提供呈現支持,主要包括輸出顯示,透明度,座標轉換,區域剪切 等。另外,Visual類同時是非託管的MilCore.dll和託管的WPF類之間的橋樑。如果一個類從Visual派生,它就可以在窗口中顯示出來。這樣,當你想創建你自定義的用戶界面時,你就可以使用Visual對象。
圖6 Visual是WPF和Micore.dll之間的橋樑
System.Windows.UIElement
UIElement類主要處理三個方面的內容:佈局,輸入和事件。該類繼承自Visual類,其中定義了很多與輸入和焦點有關的特性,例如鍵盤事件,鼠標和筆輸入等。同時,該類還包括一些與WPF事件模型有關的API。
System.Windows.FrameworkElement
FrameworkElement派生自UIElement,在UIElement的基礎上,它添加了很多其他功能,比如水平對齊,豎直對齊,邊距,邏輯樹、對象生命週期事件、支持數據綁定和動態資源引用、支持樣式和動畫等等。
System.Windows.Shapes.Shape
這個類可以用於創建基本的圖形,比如長方形,多邊形,橢圓,線和路徑等。
System.Windows.Controls.Control
這個類提供一些基本的界面控件,比如文本框。按鈕,列表框等。另外,它還添加了一些擴展屬性,比如字體,前景色和背景色等。
System.Windows.Controls.ContentControl
ContentControl用於顯示連續的一段內容。利用ContentControl,我們可以在面板上利用Label顯示多行文本。
System.Windows.Controls.ItemsControl
這是所有能夠支持多個條目顯示的控件的基類,例如列表框和樹形視圖。
System.Windows.Controls.Panel
面板(Panel)可以用做所有佈局的容器。它可以包含一個或多個子控件並且可以將他們按照佈局單位進行排列。這些容器是WPF佈局系統的基礎,並且合理地使用容器是對你的界面內容進行靈活佈局的關鍵。
第9問:能結合實例解釋一下WPF中的不同元素嗎?
爲了理解WPF中的不同元素,我們將創建一個簡單的實例“Hello World”,在這個過程中,我們將逐個解釋WPF的不同元素。
提示 :爲了完成這個示例,你需要Visual Studio 2008 Express Edition.
首先,讓我們啓動Visual Studio 2008 Express並且創建一個新項目,項目模板選擇“WPF Application”,如下圖所示:
圖7 創建新的WPF項目
一旦我們創建了“WPF Application”項目後,我們就會在項目中看到兩種文件類型:一種是XAML文件,另外一種就是界面背後的代碼文件,比如XAML.cs。XAML文件其實就是XML文件,其中包含了所有需要在Windows界面上顯示的元素。每個XAML元素對應於某個類。比如,XAML文件中的“Window”元素就對應於“WpfApplication1.Window1”類,“Button”元素對應於“System.Windows.Control.Button”類,而“Grid”元素對應於“System.Windows.Control.Grid”類。
圖8 XAML元素和類的對應關係
在這些項目文件中,“App.XAML”和“App.XAML.CS”文件是整個應用程序的入口。如果我們查看“App.XAML.CS”文件,我們會發現指向XAML文件的引用,表示這個文件需要被加載。所以,當應用程序開始執行,進入“App.XAML.CS”文件中的主函數“void main”時,它將加載“Window1.XAML”文件用於窗口的顯示。
圖9 WPF應用程序入口
我們可以將程序代碼中的方法和函數跟XAML中的UI元素事件相連接。當UI元素事件發生後,就執行相應的程序代碼。
圖10 程序和UI元素事件的連接
在上面的代碼片段中,我們可以看到按鈕的點擊事件是如何連接到“MyButton_Click”函數的。這個函數定義在XAML.CS程序文件中,通過將這個函數指定給XAML文件中按鈕元素的Click屬性,我們就可以將這個函數跟按鈕的點擊事件連接起來。現在當我們運行這段代碼,我們將看到一個按鈕。當你點擊這個按鈕後,“MyButton_Click”函數會執行並彈出一個消息框。
圖11 執行效果