WPF初印象

一、與WPF結緣

第一次接觸WPF是在2012年。學習了WinForm編程之后,了解到WPF這個非常先進的UI框架。可惜當時未能一探究竟,直到今天。

5年過去了,WPF沒像想象中大紅大紫,反而略顯沉寂。也許是微軟的統治地位不保,也許是桌面端編程淡出了人們的視線。總之,這項打算引領未來十年Windows平臺GUI開發的先進技術,似乎始終沒能推廣開來。時至今日,大部分Windows平臺的開發者仍然使用WinForm編程,因為WPF給人難用、性能差的的負面印象,即使有著炫酷的效果和先進的編程思想,也無濟于事。

不過最近恰好遇到一個WPF項目,正可趁此機會深入了解一下WPF。畢竟耳聽為虛,眼見為實,親自嘗試才知道它的好與壞。遂買了一本劉鐵猛著的《深入淺出WPF》,花幾天時間讀了一遍。起初興致勃勃,每一處都想追根究底,到了后面發現WPF的確很復雜,讀一遍根本不能完全理解,必須動手實踐,才有可能體會其中的精髓。所以本文簡單談談我對WPF的初印象,算作第一次學習WPF的一些理解和體會。

二、為什么用WPF

Windows GUI開發從過去的MFC到WinForm,再到今天的WPF,每一次改變都帶來了技術和思想上的巨大革新。記得當年大一的時候,有一門課還專門講MFC編程,MFC尚且老當益壯。現在還有誰會用MFC做Windows開發呢,除非是給自己找不痛快。就像上一次技術升級一樣,這次從WinForm到WPF的變革也需要經歷很長的過程。雖然WinForm看起來已經很好用了,但在新的思想和新的技術蓬勃發展的今天,WinForm已經難以勝任軟件開發的需求,主要體現在這兩個方面:

  • UI和邏輯代碼嚴重耦合
  • 沒有專業的UI設計平臺

其中第一條是WinForm最致命的缺陷,采用事件響應機制,無可避免地難以做到View層和Controller層分離,也就無法真正實現MVC架構。而WPF采用數據綁定(Data Binding)解決了這個問題,這種數據驅動的思想后來被廣泛應用于Web開發,比如AngularJS、Vue.js等等。基于數據綁定,WPF用路由事件代替了WinForm的事件系統,增加了命令系統,增加了功能強大的控件模板和數據模板,以及方便的繪圖和動畫接口。

第二條缺陷導致了WinForm無法制作出精美的界面,更沒有炫酷的效果。相比之下,WPF在這方面做的非常到位,提供了專門設計界面的Blend軟件,設計師用Blend畫出界面,自動生成XAML代碼,從而與程序員后端代碼無縫對接。

可以說,WPF在設計理念上比WinForm前進了一大步。下面對其中的幾個特性做簡單的介紹。

三、XAML語言

與WinForm完全使用C#編寫布局代碼不同(雖然這些代碼是自動生成的),WPF使用了一種全新的標記語言XAML(讀作zaml)來描述界面布局。它的語法類似于XML,但卻有著與HTML+CSS+JavaScript等同的強大能力,而且有Blend這么好用的可視化編輯器,簡直是Windows程序員的福音。

就像JSP會被編譯為Servlet一樣,XAML也會被編譯成C#代碼,并與程序員編寫的后端代碼合并成為完整的類。因而與XAML窗體對應的后端代碼類名前會加上partial關鍵字,這是C#靈活性的體現。

XAML其實與C#類庫有著密切的聯系。比如XAML中的標簽就是C#中的類,標簽中的x:Name屬性就是C#類的實例,標簽中的其它屬性都是C#類的屬性等等。標簽的嵌套關系構成了一棵樹,稱為Logical Tree,這是與WinForm界面截然不同的結構。WinForm的界面控件不具有嵌套關系,各自獨立,因而一旦需要關聯起來就要編寫大量的邏輯代碼。而具有樹狀關系的控件之間發生聯系時消息可以很自然地沿著樹結構傳遞,簡化了邏輯代碼,同時體現出數據驅動的理念。

在UI布局方面,如果體驗過Qt的QML布局,可以發現XAML與它很相似。這類布局方式思路清晰,嵌套關系明確,設計出的布局適應性強。相比之下, HTML布局總讓我很頭疼,難以設計出想要的效果。

XAML的樣式(Style)提供了類似CSS的效果。可以為一類控件設置統一的樣式。再配合上模板(Template),無需創建自定義控件就可以獲得各種各樣的效果。

WPF還提供了豐富的繪圖和動畫效果,這已經遠遠超出了WinForm所能提供的功能。

四、綁定(Binding)

綁定的概念現在已經深入人心,沒有綁定何來數據驅動呢。在WPF中,把控件顯示的內容與數據源綁定后,就能實現數據的雙向傳輸,也就是說,數據源中數據的變化會直接體現在界面上,界面上用戶對數據的修改也會直接反映到數據源中。這一功能的直接好處就是省略了兩個事件處理方法,一個是數據源數據更改事件,另一個是控件的數據更改事件。別小看這兩處節約,大部分的界面邏輯代碼都花在這樣的事情上。比如讓文本框的數字跟隨進度條變化,檢驗輸入的用戶名是否滿足格式要求,將實體類的成員顯示在表單中等等。有了數據綁定,就可以減少大量的邏輯代碼,只需要在XAML中簡單地加上綁定依賴即可。

綁定的源可以是各種各樣的類型,比如對象、列表、ADO.NET對象、XML、LINQ檢索結果等等。數據在綁定的源和目標之間傳輸的時候,可以添加數據校驗和數據轉換,從而實現各種各樣的需求。

五、路由事件

WPF中的事件稱為路由事件。與WinForm中的事件不同的是,路由事件并不直接指定接收者,而是沿著界面元素樹Logical Tree從下往上傳播。每經過一個結點就檢查該結點是否聲明了事件處理器,如果有則處理,否則繼續向上傳播。這樣做的好處是事件觸發者和事件接收者完全解耦,事件接收者甚至不知道事件是從哪里發出的,它只關心自己需要處理哪一類事件就可以了,而不必關心事件從哪里來。

WPF受人詬病的性能問題,我猜就和路由事件這類特性有關。由于事件的發送者和接收者完全解耦,在模塊分離的同時也造成了資源浪費,許多不必接收該事件的結點也會收到該事件,它們只能檢查后放行,讓事件繼續向上尋找下一個接收者。直觀上看,這顯然會耗費更多的時間。看來任何事情都有兩面性,過于降低耦合卻造成了性能損失,兩者不可兼得。

六、我的感受

除了上面介紹的內容外,WPF還有命令(Command)、資源等神奇的特性,這里就不一一介紹了。

總體上,WPF是個非常好的框架,設計精良,功能強大。今天廣為流行的數據驅動理念,竟然早在2007年微軟推出的WPF中體現得淋漓盡致,不得不感嘆微軟開發團隊的洞見。對于大型的Windows應用程序開發,采用WPF不失為一個最好的選擇。

然而WPF上手還是不太容易,想要完全按照數據驅動的理念編程,需要對這個框架有充分的了解。否則初學者很容易按照WinForm的思路寫代碼,那就畫虎不成反類犬了。

本文并未詳細討論WPF的技術細節,想要真正掌握這項技術的朋友,建議買一本劉鐵猛的《深入淺出WPF》仔細研讀,這本書講得很透徹,很適合初學者閱讀。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 目錄 什么是WPF? WPF的歷史? 為什么要用WPF及WPF作用 WPF與winForm區別? 什么是WPF? ...
    灬52赫茲灬閱讀 5,883評論 2 11
  • 什么是Xaml Xaml(Extensible Application Markup Language) 可擴展應...
    北風知我意閱讀 672評論 0 1
  • 第二章:城邦 “事情就這么簡單,我被開除了。”肖維祁放下手里的茶杯很坦然的對我說,“本來我也不打算念了。” “你就...
    南城瘋子閱讀 508評論 0 0
  • 文/如雨隨行 前方有條河 河水清清泛微波 天上白云朵朵 水中倒影一個 魚兒自在游 人影隨波動 好想有艘船 船上載你...
    如雨隨行閱讀 228評論 5 11
  • ###1. 谷歌瀏覽器 Chrome是個優秀的瀏覽器,當然你也可以使用自帶的Firefox,主要看個人使用習慣。推...
    小魚Zero閱讀 850評論 1 17