wpf佈局遞迴

ggtc發表於2024-04-22

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沒有過載它。我們只在有必要的自定義繪製時過載。

相關文章