什么是Xaml
Xaml(Extensible Application Markup Language) 可擴(kuò)展應(yīng)用程序標(biāo)記語(yǔ)言,該語(yǔ)言基于xml實(shí)現(xiàn)的進(jìn)行了相應(yīng)的擴(kuò)展组砚。該語(yǔ)言很容易進(jìn)行擴(kuò)展八千,有點(diǎn)類似B/S編程中的代碼后置,前端是HTML与殃,后臺(tái)是業(yè)務(wù)邏輯和相關(guān)處理代碼母赵。
還有一點(diǎn)是我們反復(fù)強(qiáng)調(diào)的,XAML并不是HTML授药。盡管XAML在元素的聲明士嚎、程序樣式的設(shè)置和指定事件處理程序上都和HTML非常類似呜魄,但是XAML是基于XML的,它是WPF的外在表現(xiàn)形式莱衩。而HTML主是一種標(biāo)記語(yǔ)言爵嗅,僅僅是用來為瀏覽器呈現(xiàn)頁(yè)面內(nèi)容。XAML除了用來呈現(xiàn)信息和請(qǐng)求用戶輸入等基本的功能外膳殷,它還包含了一些高級(jí)的特性操骡,例如它提供了對(duì)動(dòng)畫和3D眾多方面的支持。
xaml語(yǔ)言赚窃,微軟提供了可視化的設(shè)計(jì)工具blend册招。基于blend創(chuàng)建的的界面模型及效果勒极,都可以存儲(chǔ)或者轉(zhuǎn)換為xaml格式的代碼是掰,這樣就可以大大的提高了團(tuán)隊(duì)中的設(shè)計(jì)人員和開發(fā)人員之間的協(xié)作,減少了設(shè)計(jì)人員原型效果辱匿,開發(fā)人員無(wú)法實(shí)現(xiàn)键痛,設(shè)計(jì)人員可以自行設(shè)計(jì)后,轉(zhuǎn)換為xaml代碼匾七。
關(guān)于xaml更多的內(nèi)容絮短,可以參考維基百科或百度知道。
相關(guān)的簡(jiǎn)單說明如下:
image
對(duì)于熟悉XML的同仁昨忆,應(yīng)該沒有什么難理解的丁频。
什么是路由事件
我們先來看看MSDN給出的定義:
功能定義:路由事件是一種可以針對(duì)元素樹中的多個(gè)偵聽器(而不是僅針對(duì)引發(fā)該事件的對(duì)象)調(diào)用處理程序的事件。
實(shí)現(xiàn)定義:路由事件是一個(gè) CLR 事件邑贴,可以由 RoutedEvent 類的實(shí)例提供支持并由 Windows Presentation Foundation (WPF) 事件系統(tǒng)來處理席里。
我們來解釋下MSDN給出的定義:
1、傳統(tǒng)方式:
image
對(duì)應(yīng)的xaml代碼和后臺(tái)代碼如下:
image
后臺(tái)對(duì)于的處理如下:
image
當(dāng)然采用如下的方式也是可行的拢驾。
image
image
后臺(tái)代碼修改為:
image
2奖磁、WPF的路由方式:
路由事件使用以下三個(gè)路由策略之一:
冒泡:針對(duì)事件源調(diào)用事件處理程序。路由事件隨后會(huì)路由到后續(xù)的父元素繁疤,直到到達(dá)元素樹的根咖为。大多數(shù)路由事件都使用冒泡路由策略。冒泡路由事件通常用來報(bào)告來自不同控件或其他 UI 元素的輸入或狀態(tài)變化稠腊。
直接:只有源元素本身才有機(jī)會(huì)調(diào)用處理程序以進(jìn)行響應(yīng)案疲。這與 Windows 窗體用于事件的“路由”相似。但是麻养,與標(biāo)準(zhǔn) CLR 事件不同的是褐啡,直接路由事件支持類處理(類處理將在下一節(jié)中介紹)而且可以由 EventSetter 和 EventTrigger 使用。
隧道:最初將在元素樹的根處調(diào)用事件處理程序鳖昌。隨后备畦,路由事件將朝著路由事件的源節(jié)點(diǎn)元素(即引發(fā)路由事件的元素)方向低飒,沿路由線路傳播到后續(xù)的子元素。在合成控件的過程中通常會(huì)使用或處理隧道路由事件懂盐,這樣褥赊,就可以有意地禁止顯示復(fù)合部件中的事件,或者將其替換為特定于整個(gè)控件的事件莉恼。在 WPF 中提供的輸入事件通常是以隧道/冒泡對(duì)實(shí)現(xiàn)的拌喉。隧道事件有時(shí)又稱作 Preview 事件,這是由隧道/冒泡對(duì)所使用的命名約定決定的俐银。
在傳統(tǒng)的方式中尿背,我們必須對(duì)每個(gè)事件源進(jìn)行事件處理綁定,如果我們新增加新的對(duì)象或者新的事件源捶惜,那么我們還需要添加新的綁定田藐。而這一切在WPF,都被統(tǒng)一處理和考慮了吱七,下面汽久,我們以冒泡為例來簡(jiǎn)單說明。
image
冒泡的順序
image
修改后臺(tái)代碼如下:
image
關(guān)于邏輯樹與可視化樹踊餐,我們這里解釋下:
邏輯樹:簡(jiǎn)單來說景醇,就是我們從界面上來看 界面的可視化基本組成部分,這就構(gòu)成了窗口的一個(gè)邏輯樹吝岭。邏輯樹始終存在于WPF的UI中三痰,不管UI是用XAML編寫還是用代碼編寫。WPF的每個(gè)方面(屬性苍碟、事件、資源等等)都是依賴于邏輯樹的
image
可視樹:可視樹基本上是邏輯樹的一種擴(kuò)展撮执。邏輯樹的每個(gè)結(jié)點(diǎn)都被分解為它們的核心視覺組件微峰。邏輯樹的結(jié)點(diǎn)對(duì)我們而言基本是一個(gè)黑盒。而可視樹不同抒钱,它暴露了視覺的實(shí)現(xiàn)細(xì)節(jié)蜓肆。下面是Visual Tree結(jié)構(gòu)就表示了上面四行XAML代碼的視覺樹結(jié)構(gòu)。
image
可視樹谋币,將界面組成的所有對(duì)象本身的內(nèi)容進(jìn)行了解析仗扬,例如button 按鈕,他的內(nèi)容蕾额,是有contentpresenter和textblock構(gòu)成早芭。
關(guān)于邏輯樹和可視樹的更多介紹,可參考MSDN的介紹诅蝶。
我這里給出簡(jiǎn)單的獲取邏輯樹和可視樹的代碼:
image
都上WPF本身提供了一些方法退个。采用遞歸的方式募壕。
我們接著上面的關(guān)于查看事件源的地方:
image
經(jīng)過上面我們看到了,默認(rèn)情況下,WPF的事件是采用冒泡的方式進(jìn)行事件的傳遞的语盈,那么我們?nèi)绾尾捎闷渌亩N策略呢舱馅?
我們?cè)賮砜聪滤淼朗录淼朗录捻樞蛉缦拢阂肕SDN中的解釋圖:
輸入事件的冒泡和隧道
事件的處理順序如下所示:
針對(duì)根元素處理 PreviewMouseDown(隧道)刀荒。
針對(duì)中間元素 1 處理 PreviewMouseDown(隧道)代嗤。
針對(duì)源元素 2 處理 PreviewMouseDown(隧道)。
針對(duì)源元素 2 處理 MouseDown(冒泡)缠借。
針對(duì)中間元素 1 處理 MouseDown(冒泡)干毅。
針對(duì)根元素處理 MouseDown(冒泡)。
我們來驗(yàn)證下烈炭,我們以此處理所有的preview事件溶锭,看看是不是按照上面介紹的方式去處理的。
image
對(duì)應(yīng)的后臺(tái)代碼如下:
image
運(yùn)行符隙,后查看輸出結(jié)果:
image
與我們預(yù)期的一致趴捅。關(guān)于更多的路由事件,我們后面通過單獨(dú)的章節(jié)來說明霹疫。
WPF基礎(chǔ)控件
系統(tǒng)默認(rèn)提供的基礎(chǔ)控件:
image
image
有些由于自己也沒有進(jìn)行深入的使用拱绑,可能就不會(huì)介紹太詳細(xì)。
關(guān)于控件的基本使用丽蝎,會(huì)在后續(xù)進(jìn)行深入的討論和演示猎拨。
什么是依賴屬性
DependencyProperty(依賴屬性):Windows Presentation Foundation (WPF) 提供了一組服務(wù),這些服務(wù)可用于擴(kuò)展公共語(yǔ)言運(yùn)行時(shí) (CLR) 屬性的功能屠阻,這些服務(wù)通常統(tǒng)稱為 WPF 屬性系統(tǒng)红省。由 WPF 屬性系統(tǒng)支持的屬性稱為依賴項(xiàng)屬性。
WPF界面控件中的屬性国觉,都可以稱作是依賴屬性吧恃,通過依賴屬性,我們能夠?qū)崿F(xiàn)viewModel與界面元素屬性之間進(jìn)行綁定麻诀。
依賴屬性與我們平時(shí)說的屬性有區(qū)別的痕寓。
1、傳統(tǒng)的屬性
image
這沒啥好說的蝇闭,就是我們針對(duì)對(duì)象進(jìn)行了封裝呻率。
假設(shè),我們有一個(gè)類呻引,有很多的屬性礼仗,而且,又被多個(gè)對(duì)象繼承,我們知道繼承的特性藐守,那么肯定會(huì)有很多的屬性挪丢,本身我們可能基本不適用,那么該屬性卢厂,還是會(huì)被創(chuàng)建的時(shí)候?qū)嵗睿敲从袥]有什么辦法,我們減少這樣的開銷呢慎恒?WPF針對(duì)這樣的情況提出了依賴屬性的概念任内。
2、依賴屬性:
查看其基本的聲明和定義:在注釋中描述:通過方法設(shè)置的屬性融柬,數(shù)據(jù)綁定死嗦,動(dòng)畫,樣式等粒氧。
image
依賴屬性就是自己自己沒有值越除,通過Binding從數(shù)據(jù)源獲得值,就是依賴在別人身上外盯,擁有依賴屬性的對(duì)象稱為依賴對(duì)象摘盆。
我們來看看WPF控件的基本繼承鏈
Object類:在.Net中所有類型的根類型
DispatcherObject類:WPF 中的大多數(shù)對(duì)象是從 DispatcherObject 派生的,這提供了用于處理并發(fā)和線程的基本構(gòu)造饱苟。WPF 基于調(diào)度程序?qū)崿F(xiàn)的消息系統(tǒng)孩擂。
DependencyObject類:表示一個(gè)參與依賴項(xiàng)屬性系統(tǒng)的對(duì)象。
Visual類:為 WPF 中的呈現(xiàn)提供支持箱熬,其中包括命中測(cè)試类垦、坐標(biāo)轉(zhuǎn)換和邊界框計(jì)算。
UIElement 類: WPF 核心級(jí)實(shí)現(xiàn)的基類城须,該類建立在 Windows Presentation Foundation (WPF) 元素和基本表示特征基礎(chǔ)上蚤认。
FrameworkElement 類:為 Windows Presentation Foundation (WPF) 元素提供 WPF 框架級(jí)屬性集、事件集和方法集糕伐。此類表示附帶的 WPF 框架級(jí)實(shí)現(xiàn)砰琢,它是基于由UIElement定義的 WPF 核心級(jí) API 構(gòu)建的。
Control類:表示 用戶界面 (UI) 元素的基類赤炒,這些元素使用 ControlTemplate 來定義其外觀氯析。
ContentControl類:表示包含單項(xiàng)內(nèi)容的控件亏较。
ItemsControl類:表示一個(gè)可用于呈現(xiàn)項(xiàng)的集合的控件莺褒。
Decorator類:提供在單個(gè)子元素(如 Border 或 Viewbox)上或周圍應(yīng)用效果的元素的基類。PPT中鼠標(biāo)滑過文本框后雪情,出現(xiàn)邊框
Image類:表示顯示圖像的控件遵岩。
MediaElement類:表示包含音頻和/或視頻的控件。自己封裝一個(gè)視頻播放器
Panel類:為所有 Panel 元素提供基類。使用 Panel 元素在 Windows Presentation Foundation (WPF) 應(yīng)用程序中放置和排列子對(duì)象尘执。
Sharp類:為 Ellipse舍哄、Polygon 和 Rectangle 之類的形狀元素提供基類。
image
關(guān)于依賴屬性的聲明和更詳細(xì)的內(nèi)容誊锭,我們?cè)诤罄m(xù)的單獨(dú)的章節(jié)中有更詳盡的介紹表悬。
幾種應(yīng)用依賴屬性的場(chǎng)景:
希望可在樣式中設(shè)置屬性。
希望屬性支持?jǐn)?shù)據(jù)綁定丧靡。
希望可使用動(dòng)態(tài)資源引用設(shè)置屬性蟆沫。
希望從元素樹中的父元素自動(dòng)繼承屬性值。
希望屬性可進(jìn)行動(dòng)畫處理温治。
希望屬性系統(tǒng)在屬性系統(tǒng)饭庞、環(huán)境或用戶執(zhí)行的操作或者讀取并使用樣式更改了屬性以前的值時(shí)報(bào)告。
希望使用已建立的熬荆、WPF 進(jìn)程也使用的元數(shù)據(jù)約定舟山,例如報(bào)告更改屬性值時(shí)是否要求布局系統(tǒng)重新編寫元素的可視化對(duì)象。依賴對(duì)象創(chuàng)建時(shí)并不包含存儲(chǔ)數(shù)據(jù)空間卤恳。WPF中必須使用依賴對(duì)象作為依賴屬性的宿主累盗。
后面的章節(jié),我們會(huì)結(jié)合具體的案例纬黎,來說明如何使用依賴屬性幅骄。