WPF面板自定義方法介紹
WPF作為一種方便使用的圖形界面顯示工具,幫助開發人員完成了許多工能。在WPF中,有很多種面板,比如Grid, StackPanel等,這讓我們的界面布局更加的靈活,但也許這些WCF面板并不能完全滿足你的需求,這時你需要自定義面板來滿足你的布局要求. #t#
1,WCF面板布局是如何實現的
WPF 布局引擎采用了一種遞歸的方式來實現控件及其子控件的布局,大致過程是這樣的:要實現控件A的布局,那么先要實現A的子控件a1,a2,a3...的布局,要實現a1的布局,那么得實現a1的子控件a11,a12,a13...的布局,如此循環,然后但子控件的布局完成后,在完成父控件的布局,最后遞歸回去,遞歸結束,布局才算完成.
控件的最終大小和位置是由該控件和父控件相磋商來完成的,父控件先給出其能給予子控件的力所能及的布局空間,子控件在反饋給父控件一個自己的期望值,父控件最后根據自己所擁有的空間大小與子控件的期望值分配一定的空間給子控件并返回自己的大小.這一系列過程是通過重寫面板的MeasureOverride和ArrangeOverride方法來完成的.
2,Size MeasureOverride(Size availableSize)方法
該方法為WCF面板布局中控件所需要的空間大小進行評估. 參考如下代碼:
- protected override
- Size MeasureOverride(Size
availableSize) {- Size childrenSize =
new Size(0, 0);- foreach (UIElement child in
this.Children) { child.Measure
(new Size(Double.PositiveInfinity
,Double.PositiveInfinity));
childrenSize.
Width += child.DesiredSize.Width;
childrenSize.Height += child.
DesiredSize.Height;- }
- return childrenSize;
- }
在MeasureOverride階段我們對WCF面板中的每個Child調用了其Measure(Size sz)方法,該方法的作用是父控件告訴子控件其預計要分配給子控件的空間大小,對Child調用了該Measure方法后,子控件會在其內部給父控件一個回應以便告訴父控件它所期望的大小,而子控件的該期望值便保存在其child.DesiredSize中.如果Measure方法中傳入的是正無窮大 (new Size(Double.PositiveInfinity,Double.PositiveInfinity))時,相當于父控件在對子控件說"盡管說出你所需要的大小吧,如果可以的話全世界都可以給你".
MeasureOverrice方法中的availableSize參數正是其父控件(你編寫的面板控件以后在實際使用時其父控件)對其調用Measure方法時傳入的值(減去一些邊界值,比如要減掉Margin等)
MeasureOverride方法的返回值正是其告訴其父控件的期望值,即是其父控件(你編寫的面板控件以后在實際使用時其父控件)對其調用Measure方法后,其DesiredSize值
注意:作為父控件,你可以很慈愛地僅可能地滿足子控件的需要(盡管不一定有這能力),所以可以在對子控件調用Measure方法時傳入一個正無窮大的尺寸, 但作為子控件,你不能貪婪地向父控件索要正無窮大的空間,所以我們不能將正無窮大作為MeasureOverride方法的返回值,也不能直接將該方法的 availableSize參數作為返回值(因為你的父控件有可能將正無窮大作為該參數傳遞給你)
3,Size ArrangeOverride(Size finalSize)方法
該方法作用在于為WCF面板子控件提供布局空間即排列子控件并返回自身大小,參考下面的代碼:
- protected override
- Size ArrangeOverride(Size
finalSize) {- Point childPos = new Point(0, 0);
- foreach (UIElement child in
this.Children)
{ child.Arrange(new Rect
(childPos, new
Size(child.DesiredSize.Width,
finalSize.
Height))); childPos.X += child.
RenderSize.Width;- }
- return finalSize;
- }
該方法對每個Child調用Arrange方法,Arrange方法中傳入的Rect結構告訴子控件其被安排在那個空間內進行布局,然后子元素會根據自己得到的空間以及自己的對齊屬性(XXXAlignment)進行放置,放置完成后子控件的大小等便得到了確定,而該值便存放在子控件的 RenderSize中(即是ActualWidth與ActualHeight).
控件本身也可以根據子控件占用的實際空間大小來決定自己的大小,也可以直接將得到的空間大小(即是ArrangeOverride方法中的finalSize參數)作為自己的最終大小返回
ArrangeOverride方法中的finalSize參數是該控件的父控件(你編寫的面板控件以后在實際使用時其父控件)在對該控件調用Arrange方法時傳入的Rect的大小,正如該控件對其子控件調用Arrange方法一樣.
注意:Child的Arrange方法只是給定一個空間讓WCF面板子控件在此空間內進行擺放,該空間并沒有決定子控件的具體位置和大小,這還得取決于子控件的其它屬性,比如HorizontalAlignment與VerticalAlignment等. 在Arrange期間,系統會自動進行對齊(Alignment)操作.