什么是Xaml
Xaml(Extensible Application Markup Language) 可擴展應(yīng)用程序標(biāo)記語言,該語言基于xml實現(xiàn)的進行了相應(yīng)的擴展。該語言很容易進行擴展,有點類似B/S編程中的代碼后置,前端是HTML,后臺是業(yè)務(wù)邏輯和相關(guān)處理代碼。
還有一點是我們反復(fù)強調(diào)的,XAML并不是HTML。盡管XAML在元素的聲明、程序樣式的設(shè)置和指定事件處理程序上都和HTML非常類似,但是XAML是基于XML的,它是WPF的外在表現(xiàn)形式。而HTML主是一種標(biāo)記語言,僅僅是用來為瀏覽器呈現(xiàn)頁面內(nèi)容。XAML除了用來呈現(xiàn)信息和請求用戶輸入等基本的功能外,它還包含了一些高級的特性,例如它提供了對動畫和3D眾多方面的支持。
xaml語言,微軟提供了可視化的設(shè)計工具blend。基于blend創(chuàng)建的的界面模型及效果,都可以存儲或者轉(zhuǎn)換為xaml格式的代碼,這樣就可以大大的提高了團隊中的設(shè)計人員和開發(fā)人員之間的協(xié)作,減少了設(shè)計人員原型效果,開發(fā)人員無法實現(xiàn),設(shè)計人員可以自行設(shè)計后,轉(zhuǎn)換為xaml代碼。
關(guān)于xaml更多的內(nèi)容,可以參考維基百科或百度知道。
相關(guān)的簡單說明如下:
image
對于熟悉XML的同仁,應(yīng)該沒有什么難理解的。
什么是路由事件
我們先來看看MSDN給出的定義:
功能定義:路由事件是一種可以針對元素樹中的多個偵聽器(而不是僅針對引發(fā)該事件的對象)調(diào)用處理程序的事件。
實現(xiàn)定義:路由事件是一個 CLR 事件,可以由 RoutedEvent 類的實例提供支持并由 Windows Presentation Foundation (WPF) 事件系統(tǒng)來處理。
我們來解釋下MSDN給出的定義:
1、傳統(tǒng)方式:
image
對應(yīng)的xaml代碼和后臺代碼如下:
image
后臺對于的處理如下:
image
當(dāng)然采用如下的方式也是可行的。
image
image
后臺代碼修改為:
image
2、WPF的路由方式:
路由事件使用以下三個路由策略之一:
冒泡:針對事件源調(diào)用事件處理程序。路由事件隨后會路由到后續(xù)的父元素,直到到達(dá)元素樹的根。大多數(shù)路由事件都使用冒泡路由策略。冒泡路由事件通常用來報告來自不同控件或其他 UI 元素的輸入或狀態(tài)變化。
直接:只有源元素本身才有機會調(diào)用處理程序以進行響應(yīng)。這與 Windows 窗體用于事件的“路由”相似。但是,與標(biāo)準(zhǔn) CLR 事件不同的是,直接路由事件支持類處理(類處理將在下一節(jié)中介紹)而且可以由 EventSetter 和 EventTrigger 使用。
隧道:最初將在元素樹的根處調(diào)用事件處理程序。隨后,路由事件將朝著路由事件的源節(jié)點元素(即引發(fā)路由事件的元素)方向,沿路由線路傳播到后續(xù)的子元素。在合成控件的過程中通常會使用或處理隧道路由事件,這樣,就可以有意地禁止顯示復(fù)合部件中的事件,或者將其替換為特定于整個控件的事件。在 WPF 中提供的輸入事件通常是以隧道/冒泡對實現(xiàn)的。隧道事件有時又稱作 Preview 事件,這是由隧道/冒泡對所使用的命名約定決定的。
在傳統(tǒng)的方式中,我們必須對每個事件源進行事件處理綁定,如果我們新增加新的對象或者新的事件源,那么我們還需要添加新的綁定。而這一切在WPF,都被統(tǒng)一處理和考慮了,下面,我們以冒泡為例來簡單說明。
image
冒泡的順序
image
修改后臺代碼如下:
image
關(guān)于邏輯樹與可視化樹,我們這里解釋下:
邏輯樹:簡單來說,就是我們從界面上來看 界面的可視化基本組成部分,這就構(gòu)成了窗口的一個邏輯樹。邏輯樹始終存在于WPF的UI中,不管UI是用XAML編寫還是用代碼編寫。WPF的每個方面(屬性、事件、資源等等)都是依賴于邏輯樹的
image
可視樹:可視樹基本上是邏輯樹的一種擴展。邏輯樹的每個結(jié)點都被分解為它們的核心視覺組件。邏輯樹的結(jié)點對我們而言基本是一個黑盒。而可視樹不同,它暴露了視覺的實現(xiàn)細(xì)節(jié)。下面是Visual Tree結(jié)構(gòu)就表示了上面四行XAML代碼的視覺樹結(jié)構(gòu)。
image
可視樹,將界面組成的所有對象本身的內(nèi)容進行了解析,例如button 按鈕,他的內(nèi)容,是有contentpresenter和textblock構(gòu)成。
關(guān)于邏輯樹和可視樹的更多介紹,可參考MSDN的介紹。
我這里給出簡單的獲取邏輯樹和可視樹的代碼:
image
都上WPF本身提供了一些方法。采用遞歸的方式。
我們接著上面的關(guān)于查看事件源的地方:
image
經(jīng)過上面我們看到了,默認(rèn)情況下,WPF的事件是采用冒泡的方式進行事件的傳遞的,那么我們?nèi)绾尾捎闷渌亩N策略呢?
我們再來看下隧道事件,隧道事件的順序如下:引用MSDN中的解釋圖:
輸入事件的冒泡和隧道
事件的處理順序如下所示:
針對根元素處理 PreviewMouseDown(隧道)。
針對中間元素 1 處理 PreviewMouseDown(隧道)。
針對源元素 2 處理 PreviewMouseDown(隧道)。
針對源元素 2 處理 MouseDown(冒泡)。
針對中間元素 1 處理 MouseDown(冒泡)。
針對根元素處理 MouseDown(冒泡)。
我們來驗證下,我們以此處理所有的preview事件,看看是不是按照上面介紹的方式去處理的。
image
對應(yīng)的后臺代碼如下:
image
運行,后查看輸出結(jié)果:
image
與我們預(yù)期的一致。關(guān)于更多的路由事件,我們后面通過單獨的章節(jié)來說明。
WPF基礎(chǔ)控件
系統(tǒng)默認(rèn)提供的基礎(chǔ)控件:
image
image
有些由于自己也沒有進行深入的使用,可能就不會介紹太詳細(xì)。
關(guān)于控件的基本使用,會在后續(xù)進行深入的討論和演示。
什么是依賴屬性
DependencyProperty(依賴屬性):Windows Presentation Foundation (WPF) 提供了一組服務(wù),這些服務(wù)可用于擴展公共語言運行時 (CLR) 屬性的功能,這些服務(wù)通常統(tǒng)稱為 WPF 屬性系統(tǒng)。由 WPF 屬性系統(tǒng)支持的屬性稱為依賴項屬性。
WPF界面控件中的屬性,都可以稱作是依賴屬性,通過依賴屬性,我們能夠?qū)崿F(xiàn)viewModel與界面元素屬性之間進行綁定。
依賴屬性與我們平時說的屬性有區(qū)別的。
1、傳統(tǒng)的屬性
image
這沒啥好說的,就是我們針對對象進行了封裝。
假設(shè),我們有一個類,有很多的屬性,而且,又被多個對象繼承,我們知道繼承的特性,那么肯定會有很多的屬性,本身我們可能基本不適用,那么該屬性,還是會被創(chuàng)建的時候?qū)嵗敲从袥]有什么辦法,我們減少這樣的開銷呢?WPF針對這樣的情況提出了依賴屬性的概念。
2、依賴屬性:
查看其基本的聲明和定義:在注釋中描述:通過方法設(shè)置的屬性,數(shù)據(jù)綁定,動畫,樣式等。
image
依賴屬性就是自己自己沒有值,通過Binding從數(shù)據(jù)源獲得值,就是依賴在別人身上,擁有依賴屬性的對象稱為依賴對象。
我們來看看WPF控件的基本繼承鏈
Object類:在.Net中所有類型的根類型
DispatcherObject類:WPF 中的大多數(shù)對象是從 DispatcherObject 派生的,這提供了用于處理并發(fā)和線程的基本構(gòu)造。WPF 基于調(diào)度程序?qū)崿F(xiàn)的消息系統(tǒng)。
DependencyObject類:表示一個參與依賴項屬性系統(tǒng)的對象。
Visual類:為 WPF 中的呈現(xiàn)提供支持,其中包括命中測試、坐標(biāo)轉(zhuǎn)換和邊界框計算。
UIElement 類: WPF 核心級實現(xiàn)的基類,該類建立在 Windows Presentation Foundation (WPF) 元素和基本表示特征基礎(chǔ)上。
FrameworkElement 類:為 Windows Presentation Foundation (WPF) 元素提供 WPF 框架級屬性集、事件集和方法集。此類表示附帶的 WPF 框架級實現(xiàn),它是基于由UIElement定義的 WPF 核心級 API 構(gòu)建的。
Control類:表示 用戶界面 (UI) 元素的基類,這些元素使用 ControlTemplate 來定義其外觀。
ContentControl類:表示包含單項內(nèi)容的控件。
ItemsControl類:表示一個可用于呈現(xiàn)項的集合的控件。
Decorator類:提供在單個子元素(如 Border 或 Viewbox)上或周圍應(yīng)用效果的元素的基類。PPT中鼠標(biāo)滑過文本框后,出現(xiàn)邊框
Image類:表示顯示圖像的控件。
MediaElement類:表示包含音頻和/或視頻的控件。自己封裝一個視頻播放器
Panel類:為所有 Panel 元素提供基類。使用 Panel 元素在 Windows Presentation Foundation (WPF) 應(yīng)用程序中放置和排列子對象。
Sharp類:為 Ellipse、Polygon 和 Rectangle 之類的形狀元素提供基類。
image
關(guān)于依賴屬性的聲明和更詳細(xì)的內(nèi)容,我們在后續(xù)的單獨的章節(jié)中有更詳盡的介紹。
幾種應(yīng)用依賴屬性的場景:
希望可在樣式中設(shè)置屬性。
希望屬性支持?jǐn)?shù)據(jù)綁定。
希望可使用動態(tài)資源引用設(shè)置屬性。
希望從元素樹中的父元素自動繼承屬性值。
希望屬性可進行動畫處理。
希望屬性系統(tǒng)在屬性系統(tǒng)、環(huán)境或用戶執(zhí)行的操作或者讀取并使用樣式更改了屬性以前的值時報告。
希望使用已建立的、WPF 進程也使用的元數(shù)據(jù)約定,例如報告更改屬性值時是否要求布局系統(tǒng)重新編寫元素的可視化對象。依賴對象創(chuàng)建時并不包含存儲數(shù)據(jù)空間。WPF中必須使用依賴對象作為依賴屬性的宿主。
后面的章節(jié),我們會結(jié)合具體的案例,來說明如何使用依賴屬性。