2016-12-07 50 views
0

tl; dr將子元素添加到元素時 - 調用theParent.UpdateLayout();時孩子的佈局是否會更新?UpdateLayout是否更新所有子元素?

加長版

我需要調用UpdateLayout一個元素上,以獲取有關其子屬性的一些信息。

theParent.Children.Add(child); 
theParent.UpdateLayout(); 

就我所見,通過我的測試,看起來像元素的孩子的孩子也被更新了。即UpdateLayout是遞歸的。但是,檢查文檔UIElement.UpdateLayout我沒有看到我所期望的。此外,由於文檔不鼓勵我們使用這種方法,除非絕對必要,提及一些優化,我擔心這裏的測試不是要走的路 - 每種情況都可能不同。所以最後 - 是否保證UpdateLayout是遞歸的?

回答

1

佈局系統本質上是遞歸的。爲了使按鈕根據其內容自動調整自己的尺寸,它需要首先測量其子元素(即通常是TextBlock標籤),並且那些子元素也可能需要測量其子元素,等等。

當您創建一個新的UIElement時,其佈局最初是無效的(或「髒」)。這意味着該元素被標記爲「需要在下一個佈局週期中佈局」 - 佈局系統將跳過未被標記爲優化的元素作爲優化(佈局對於複雜的可視化樹尤其昂貴)。

將子元素添加到面板時,面板會自動失效,因爲面板的大小或位置可能會受其子級的影響(對於StackPanel和Grid而言是true,但對於Canvas,我想象的是這樣)。

理解佈局操作是批處理很重要。由於佈局過程是一項昂貴的操作,因此最好將其推遲到不再發生元素更新時爲止。想象一下,如果您將100個項目添加到ListView中,那麼不是每次都執行100次佈局更新,而是在將100個項目添加到列表後的某個時間點執行1次更新。

無論如何,回到你的問題,調用UpdateLayout將立即佈局任何失效的元素內的子樹根植於UpdateLayout被調用的元素,而不是等待直到延遲佈局通過。

有趣的是,該文件說

UpdateLayout請基本上等同於調用InvalidateMeasure和InvalidateArrange順序。

但它似乎並沒有實際上使被調用的元素的佈局無效,而是它只是強制立即更新已經失效的元素(但這只是我的觀察)。他們在這裏基本上非常鬆散地使用。

相關問題