




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Layout 系統(tǒng)概述 Measure前言在WPF/Silverlight當(dāng)中,如果已經(jīng)存在的Element無法滿足你特殊的需求,你可能想自定義Element,那么就有可能會(huì)面臨重寫MeasureOverride和ArrangeOverride兩個(gè)方法,而這兩個(gè)方法是WPF/SL的Layout系統(tǒng)提供給用戶的自定義接口,因此,理解Layout系統(tǒng)的工作機(jī)制,對(duì)自定義Element是非常有必要的。那么,究竟WPF/SL的Layout系統(tǒng)是怎么工作的呢?接下來,我簡(jiǎn)單的描述一下,然后,在后面的章節(jié)具體分析。簡(jiǎn)單來說,WPF的Layout系統(tǒng)是一個(gè)遞歸系統(tǒng),他有兩個(gè)子過程,總是以調(diào)用父元素的Meas
2、ure方法開始,以調(diào)用Ararnge方法結(jié)束,而進(jìn)入每個(gè)子過程之后,父元素又會(huì)調(diào)用孩子元素的Measure,完成后,又調(diào)用孩子元素的Arrange方法,這樣一直遞歸下去。而對(duì)兩個(gè)子過程的一次調(diào)用,可以看作是一次會(huì)話,可以理解為下圖所示:這個(gè)會(huì)話可以用下面一段話描述:子過程1:父根據(jù)自己的策略給孩子一個(gè)availableSize,并發(fā)起對(duì)話,通過調(diào)用孩子的Measure(availableSize)方法,詢問孩子:你想要多大的空間顯示自己?孩子接到詢問后,根據(jù)父給的availableSize以及自己的一些限制,比如Margin,Width,等等,孩子回答:我想要XXX大小的空間。父拿到孩子給的期
3、望的空間大小后,根據(jù)自己的策略開始真正給孩子分配空間,就進(jìn)入第二個(gè)子過程。子過程2:父拿到孩子的期望空間后,再根據(jù)自己的情況,決定給孩子分配finalRect大小的矩形區(qū)域,然后他發(fā)起對(duì)話,調(diào)用孩子的Arrange(finalRect)給孩子說:我給你了finalRect這么大的空間。孩子拿到這個(gè)大小后,會(huì)去布置它的內(nèi)容,并且布置完成后,會(huì)告訴父:其實(shí)我用了XXX大小的空間來繪制我自己的內(nèi)容。父知道后,什么也沒說,還是按照分配給他的finalRect去安置孩子,如果孩子最終繪制的區(qū)域大于這個(gè)區(qū)域,就被父裁剪了。Layout過程完成。通過上面兩個(gè)子過程的理解,或多或少對(duì)WPF的Layout系統(tǒng)有
4、個(gè)初步的了解,接下來的章節(jié),我具體描述Measure過程和Arrange過程具體做了哪些事情,幫助你跟深入的理解Layout系統(tǒng)。預(yù)設(shè)條件通過下面的一個(gè)預(yù)設(shè)場(chǎng)景,我們來展開Layout系統(tǒng)的講解。假定:我們需要自定義一個(gè)Panel,類型為*MyPanel*,MyPanel的父為*MyPanelParent*,也是一個(gè)Panel;MyPanel的孩子為*MyPanelChild*,也是一個(gè)Panel。切入點(diǎn)1:重寫MyPanelParent的MeasureOverride()和ArrangeOverride(),研究父如何影響孩子MyPanel的Layout;切入點(diǎn)2:重寫MyPanel.Mea
5、sureOverride()和ArrangeOverride方法,研究自身有哪些屬性影響MyPanel的Layout,以及重寫這兩個(gè)方法時(shí)應(yīng)該注意的點(diǎn);注意:后面的研究,我只基于Element的Width,也就是水平方向的維度,所有的數(shù)據(jù)都是只設(shè)置水平方向的,垂直方向設(shè)置的跟水平方向一致,但不做描述。Measure過程概述1.普通基類屬性對(duì)Measure過程的影響請(qǐng)看下面的一些設(shè)置:Window x:Class=WpfApplication1.MainWindowxmlns=xmlns:x=Title=MainWindowHeight=522Width=594Loaded=Window_Loa
6、dedxmlns:my=clr-namespace:WpfApplication1Canvas my:MyPanelParent x:Name=myPanelParent1Height=400Width=400Background=GreenCanvas.Left=10Canvas.Top=10my:MyPanel Margin=10x:Name=myPanel1Background=RedMinWidth=150Width=200MaxWidth=250/my:MyPanel Margin=10x:Name=myPanel2Background=RedMinWidth=150Width=20
7、0MaxWidth=250/my:MyPanelParent/Canvas/Window public class MyPanelParent:Panelprotected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)foreach(UIElement item in this.InternalChildren)item.Measure(new Size(120,120);/這里是入口return availableSize;protected override System.Wi
8、ndows.Size ArrangeOverride(System.Windows.Size finalSize)double x=0;foreach(UIElement item in this.InternalChildren)item.Arrange(new Rect(x,0,item.DesiredSize.Width,item.DesiredSize.Height);x+=item.DesiredSize.Width;return finalSize;public class MyPanel:Panelprotected override System.Windows.Size Me
9、asureOverride(System.Windows.Size availableSize)foreach(UIElement item in this.InternalChildren)item.Measure(availableSize);return new Size(50,50);/MyPanel返回它期望的大小protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)double xCordinate=0;foreach(UIElement item in this.I
10、nternalChildren)item.Arrange(new Rect(new Point(xCordinate,0),item.DesiredSize);xCordinate+=item.DesiredSize.Width;return finalSize;在上面的設(shè)置之后,應(yīng)用程序運(yùn)行起來之后,Window的表現(xiàn)為:分析一下設(shè)置:MyPanel1.Width=200,MyPanel1.MinWidth=150,MyPanel1.MaxWidth=250,MyPanel1.Margin=Thickness(10)MyPanel1.Measure()傳入的參數(shù)為120*120,MyPane
11、l1.MeasureOverride返回的參數(shù)為50*50分析一下結(jié)果:MyPanel1實(shí)際的畫出來的大小(紅色部分)是100*50從結(jié)果可以看出,紅色的部分受多個(gè)因素的影響,有人要問,我已經(jīng)設(shè)置了MyPanel.Width=200,可是怎么畫出來的Width卻是100;MyPanel.Height沒設(shè)置,可是畫出來的卻是50,為什么不是其他值。接下來我通過Measure的流程圖說明一下這個(gè)結(jié)果是怎么來的:看了上圖,有些人可能會(huì)看出一些端倪,也可能還不是很清晰,我按照自己的理解總結(jié)一下Measure過程究竟想干什么?1.第一點(diǎn)很清晰,MyPanelParent調(diào)用MyPanel.Measure
12、的過程是想得到MyPanel.DesiredSize,MyPanelParent需要在Arrange孩子MyPanel時(shí),參考孩子的DesiredSize,決定將孩子MyPanel安置多大的空間。2.MyPanel.DesiredSize是包含Margin以及內(nèi)容的大小空間3.MyPanel.MeasureOverride傳入的參數(shù)constrainedSize,是基類的實(shí)現(xiàn)刨去Margin的大小,然后按照MyPanel對(duì)MinWidth,MaxWidth,Width的設(shè)置計(jì)算的一個(gè)MyPanel想要的值,我們自定義時(shí)在MeasureOverride當(dāng)中不需要關(guān)心自己的Margin,以及其他基
13、類上影響Layout的屬性,只要考慮在給定參數(shù)的范圍類安排自己的內(nèi)容區(qū)域;MyPanel.MinWidth,Width,MaxWidth的設(shè)定都是針對(duì)內(nèi)容區(qū)域的,不含Margin部分4.如果不設(shè)定Width,那么可以在MeasureOverride返回的時(shí)候返回一個(gè)期望的內(nèi)容區(qū)域大小,它會(huì)被MinWidth和MaxWidth再調(diào)整一下,調(diào)整后,還有待于MyPanelParent的衡量(旁白:別瞎折騰,也別玩Layout系統(tǒng),都設(shè)置MinWidth,MaxWidth,就乖乖的呆在這個(gè)范圍內(nèi)。)5.不論MyPanel怎么設(shè)置自己的Width,MinWidth,MaxWidth,以及在Measure
14、Override返回一個(gè)大小,來表明自己期望多大的空間顯示自己的內(nèi)容,但這些都僅僅是期望的,期望是美好的,現(xiàn)實(shí)是殘酷的,這一切還必須限定在MyPanel.Measure開始時(shí)傳入的參數(shù)availableSize刨去MyPanel.Margin后的范圍內(nèi),小于這個(gè)范圍就滿足,大于這個(gè)范圍就被裁斷。(可憐呀,總是受制于父)6.影響Measure過程的參數(shù)和屬性存在一個(gè)優(yōu)先級(jí)的,大概如下所示:Measure方法參數(shù)availableSize MinWidth,Width,MaxWidth MeasureOverride返回值2.Transform對(duì)Measure過程的影響通過上面的過程,我們已經(jīng)大概
15、了解了Measure過程的工作方式,以及各個(gè)屬性是如何影響的。但是還有一個(gè)屬性我們沒有提及,但它對(duì)Measure的過程也影響甚大,這就是LayoutTransform。通過下面的兩段分析,你會(huì)看到這個(gè)屬性的具體表現(xiàn)。設(shè)置1:Window x:Class=WpfApplication1.MainWindowxmlns=xmlns:x=Title=MainWindowHeight=522Width=594Loaded=Window_Loadedxmlns:my=clr-namespace:WpfApplication1Canvas my:MyPanelParent x:Name=myPanelPa
16、rent1Height=400Width=400Background=LimeCanvas.Left=10Canvas.Top=10my:MyPanel Margin=10x:Name=myPanel1Background=RedWidth=200my:MyPanel.LayoutTransform RotateTransform Angle=90/my:MyPanel.LayoutTransform/my:MyPanel my:MyPanel Margin=10x:Name=myPanel2Background=RedMinWidth=150MaxWidth=250/my:MyPanelPa
17、rent/Canvas/Window public class MyPanelParent:Panelprotected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)foreach(UIElement item in this.InternalChildren)item.Measure(new Size(1000,800);return availableSize;protected override System.Windows.Size ArrangeOverride(Syst
18、em.Windows.Size finalSize)double x=0;foreach(UIElement item in this.InternalChildren)item.Arrange(new Rect(x,0,item.DesiredSize.Width,item.DesiredSize.Height);x+=item.DesiredSize.Width;return finalSize;public class MyPanel:Panelprotected override System.Windows.Size MeasureOverride(System.Windows.Si
19、ze availableSize)foreach(UIElement item in this.InternalChildren)item.Measure(availableSize);return new Size(80,50);protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)double xCordinate=0;foreach(UIElement item in this.InternalChildren)item.Arrange(new Rect(new Point
20、(xCordinate,0),item.DesiredSize);xCordinate+=item.DesiredSize.Width;return finalSize;運(yùn)行的表現(xiàn)為:分析一下設(shè)置:MyPanel1.LayoutTransform=new RotateTransform(90)/旋轉(zhuǎn)了90度MyPanel1.Width=200 MyPanel1.Margin=Thickness(10)MyPanel1.Measure()傳入的參數(shù)為1000*800,MyPanel1.MeasureOverride返回的參數(shù)為80*50.分析一下結(jié)果:MyPanel1實(shí)際的畫出來的大小是5020
21、0,明顯是被旋轉(zhuǎn)了90度。運(yùn)行起來,你會(huì)發(fā)現(xiàn)最終的MyPanel1.DesiredSize在Measure過程之后為70220,也就是說,它是被Transform之后的大小,明顯是被旋轉(zhuǎn)過的。另外,觀察MyPanel.MeasureOverride傳入的參數(shù),為200980,根據(jù)上一節(jié)對(duì)Measure過程的分析,MeasureOverride傳入的參數(shù)寬為200是可預(yù)知的,因?yàn)槲覀冊(cè)O(shè)置了MyPanel1.Width為200,但Height為980,明顯是MyPanel.Measure傳入的寬1000減去2*10等于980,看來在進(jìn)入MeasureOverride之前,Layout系統(tǒng)也處理了L
22、ayoutTransform對(duì)Measure過程的影響,它希望MeasureOverride不要關(guān)心自身LayoutTransform的影響。MeasureOverride結(jié)束后,返回值為8050,根據(jù)上一節(jié)對(duì)Measure過程的分析,寬為80被調(diào)節(jié)為符合自己的設(shè)置,為200,由于高沒有設(shè)置,這個(gè)50肯定會(huì)保留,因此最后在沒有Transform之前的DesiredSize應(yīng)該是22070,然而基類會(huì)將MeasureOverride返回的大小再進(jìn)行一次Transform,達(dá)到最終的DesiredSize的大小,以便Arrange的時(shí)候分配合適的空間來容納MyPanel的大小。如果你將上面例子的M
23、yPanel1.LayoutTransform設(shè)置成ScaleTransform:Window x:Class=WpfApplication1.MainWindowxmlns=xmlns:x=Title=MainWindowHeight=522Width=594Loaded=Window_Loadedxmlns:my=clr-namespace:WpfApplication1Canvas my:MyPanelParent x:Name=myPanelParent1Height=400Width=400Background=LimeCanvas.Left=10Canvas.Top=10my:My
24、Panel Margin=10x:Name=myPanel1Background=RedWidth=200my:MyPanel.LayoutTransform ScaleTransform ScaleX=2ScaleY=2/my:MyPanel.LayoutTransform/my:MyPanel my:MyPanel Margin=10x:Name=myPanel2Background=RedMinWidth=150MaxWidth=250/my:MyPanelParent/Canvas/Window然后再觀察myPanel.MeasureOverride傳入的參數(shù),為200390,首先20
25、0是可預(yù)知的,因?yàn)樵O(shè)置了Width屬性,而390是怎么回事呢,其實(shí)為Measure傳入的1000800的高800減去Margin為20后得到780,然后根據(jù)LayoutTransform將高縮小2倍之后得到的390,因此傳入的參數(shù)就是200390,可見,Layout系統(tǒng),在進(jìn)入MeasureOverride之前,他希望,MeasureOv erride只關(guān)心內(nèi)容怎么布置,而不需要關(guān)心基類屬性的設(shè)置對(duì)MeasureOverride的影響。由于MeasureOverride的返回值依然是8050,可推理,80被調(diào)節(jié)為200,50被保留,沒有Transform之前的值應(yīng)該是20050。因?yàn)榛愡€要進(jìn)
26、行Transform,因此,內(nèi)容區(qū)域的真實(shí)的大小應(yīng)該是400100,再加上Margin之后,最終的DesiredSize肯定為420*120,你可以嘗試調(diào)試給出的代碼。3.Measure過程的總結(jié)Measure過程的總結(jié)通過上面的過程分析,我相信你或多或少對(duì)WPF的Layout系統(tǒng)的Measure過程有了更進(jìn)一步的了解,其實(shí)還有一些因素影響Measure的過程,比如UseLayoutRounding屬性,在進(jìn)入MeasureOverride之前和之后,基類都被將參數(shù)根據(jù)DPI進(jìn)行Rounding,這個(gè)過程知道就行了,不需要在自己的MeasureOverride里面關(guān)心。我們總結(jié)一下哪些屬性和參
27、數(shù)會(huì)影響Measure的過程:MyPanel.Measure傳入的參數(shù)availableSize,MyPanel的MinWidth,Width,MaxWidth,Margin,UseLayoutRounding,LayoutTransform,MeasureOverride的返回值。Measure過程相關(guān)問題解答Q1:什么是Layout Slot?什么時(shí)候能獲取到?在哪里獲取?Layout Slot就是調(diào)用Arrange方法的時(shí)候,傳入的參數(shù)finalRect,這是父分配給子的容納Margin以及內(nèi)容區(qū)域的矩形空間;當(dāng)Arrange過程結(jié)束后,你可以拿到;通過調(diào)用靜態(tài)類LayoutInform
28、ation.GetLayoutSlot(FrameworkElement element)方法可以拿到。Q2:什么是Layout Clip?什么時(shí)候能獲取到?在哪里獲取?Layout Clip只的是當(dāng)內(nèi)容區(qū)域要繪制的大小,大于LayoutSlot刨去Margin區(qū)域后的大小,這時(shí)候,內(nèi)容區(qū)域就會(huì)被Clip,超出的部分會(huì)被Clip掉,而剩下的可顯示的部分就是Layout Clip,他是一個(gè)Geometry。Arrange過程結(jié)束后,可以拿到;通過調(diào)用靜態(tài)類LayoutInformation.GetLayoutClip(FrameworkElement element)方法可以拿到。如果內(nèi)容區(qū)域可
29、以完全顯示在Layout Slot刨去Margin的區(qū)域內(nèi),LayoutClip為Null。Q3:在父的MeasureOverride當(dāng)中調(diào)用孩子的Measure方法時(shí),傳入的參數(shù)有沒有什么限制?有,確保availableSize.Width和Height不是NaN;但可以是Infinity Q4:在進(jìn)入自己的MeasureOverride方法后,面對(duì)參數(shù)我該咋辦?首先,心里應(yīng)該明白,傳入的參數(shù)已經(jīng)是基類刨去自己的Margin,并且考慮了基類影響Measure過程的屬性之后的值。其次,看自身有沒有自定義的,并且影響Layout的屬性,根據(jù)自己的內(nèi)容要求,或者孩子的情況,調(diào)用孩子的Measure方法,并傳入希望孩子限定在多大范圍內(nèi)空間。最后,返回一個(gè)自己期望的Size。這里應(yīng)該注意的點(diǎn):1.調(diào)用孩子的Measure方法時(shí),傳入的參數(shù),是你限定孩子的最大空間,用來顯示孩子的Margin以及內(nèi)容區(qū)域的,而孩子不管最終期望的大小有多少,都會(huì)被你給他的availableSize裁剪。2.根據(jù)自身的策略返回一個(gè)期望的值,這個(gè)期望的值應(yīng)該是在自己的MinWidth,Width,MaxWidth限定的范圍呢,如果沒有,基類還會(huì)強(qiáng)行調(diào)整。3.基類調(diào)整后的值還會(huì)被父?jìng)魅氲腶vailableSize再次調(diào)整,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 植物提取物AI智能設(shè)備行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 科學(xué)實(shí)驗(yàn)俱樂部行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報(bào)告
- 海洋世界行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 倉(cāng)儲(chǔ)庫(kù)存管理系統(tǒng)企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 海域使用論證服務(wù)行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 2024年度吉林省護(hù)師類之社區(qū)護(hù)理主管護(hù)師能力測(cè)試試卷B卷附答案
- 校園足球聯(lián)賽組織與實(shí)施計(jì)劃
- 2025年移動(dòng)通訊手機(jī)配套集成電路合作協(xié)議書
- 金融機(jī)構(gòu)行政管理工作總結(jié)與風(fēng)險(xiǎn)計(jì)劃
- 小學(xué)科學(xué)創(chuàng)新實(shí)踐工作計(jì)劃
- 非暴力溝通 情緒篇
- 人民醫(yī)院整形外科臨床技術(shù)操作規(guī)范2023版
- 2023年(第九屆)全國(guó)大學(xué)生統(tǒng)計(jì)建模大賽 論文模板及說明
- 2023-爾雅《星海求知:天文學(xué)的奧秘》課后章節(jié)答案
- LY/T 1955-2022林地保護(hù)利用規(guī)劃林地落界技術(shù)規(guī)程
- 大學(xué)成績(jī)單(大專)
- 專練11(30題)(網(wǎng)格作圖題)2022中考數(shù)學(xué)考點(diǎn)500題(吉林)解析版
- JJF 1367-2012烘干法水分測(cè)定儀型式評(píng)價(jià)大綱
- 醫(yī)院麻醉藥品、精神藥品考試試題及答案
- GB/T 31586.1-2015防護(hù)涂料體系對(duì)鋼結(jié)構(gòu)的防腐蝕保護(hù)涂層附著力/內(nèi)聚力(破壞強(qiáng)度)的評(píng)定和驗(yàn)收準(zhǔn)則第1部分:拉開法試驗(yàn)
- “三重一大”事項(xiàng)決策情況記錄表
評(píng)論
0/150
提交評(píng)論