wpf佈局遞迴的呼叫到底是怎樣的順序?我一直挺模糊。
按照繼承順序。
已知:
1.1.UIElement:宣告瞭Measure
1.2.UIElement:宣告瞭MeasureCore,返回Size(0,0)
1.3.UIElement:Measure呼叫了this.MeasureCore
2.1.FrameworkElement:宣告瞭MeasureOverride返回Size(0,0)
2.2.FrameworkElement:過載MeasureCore中呼叫了this.MeasureOverride
2.3.FrameworkElement:MeasureCore是封閉的
3.1.Control:過載MeasureOverride中呼叫了child.Measure
3.2.Panel:未過載MeasureOverride
4.1.Window:過載MeasureOverride呼叫了child.Measure
4.2.UserControl:未過載MeasureOverride
4.3.Grid:過載MeasureOverride中對於每個孩子呼叫了child.Measure
能夠整理出來的
this.Measure=>MeasureCore=>MeasureOverride=>child.Measure的呼叫形成了一個遞迴,這個順序是確定的。
而且一般來說,this.Measure=>MeasureCore=>MeasureOverride的呼叫是固定下來了的。MeasureOverride=>child.Measure的呼叫則看我們自定義控制元件的繼承了。
如果是繼承Control,那麼可以呼叫base.MeasureOverride()或者顯式呼叫child.Measure就能繼續這個遞迴;如果是繼承FrameworkElement或Panel,則只能我們自己顯式呼叫child.Measure了。
問題是在一個窗體中,觸發這個遞迴的第一次this.Measure呼叫在在哪裡進行的?
怎麼看待Measure和Arrange兩個階段
Measure階段的原則是子元素會根據其內容的需求返回尺寸
Arrange階段的原則是子元素按照父控制元件給的尺寸設定自己的尺寸
所以重要的是我們先確定需要實現哪種佈局,然後第一點是就要在Arrange階段給子控制元件一個佈局規則對應的值。而如何計算給子控制元件的值,可以放在可以Measure結束後Arrange開始前的任何地方。第二點是我們要返回多大的值,是決定於子控制元件,還是自己。
最後一個階段,Render
OnRender定義於UIElement中,在Arrange函式中被呼叫,呼叫DrawContext繪製控制元件。FrameworkElement沒有過載它,Control沒有過載它。我們只在有必要的自定義繪製時過載。