2009年9月11日 星期五

在WPF中的畫面重排(Measure & Arrange)

WPF相較於前代的Form最大的變化,就是把展示的部分做了很大的改動
會多做一些自動化(如不需要重繪)或最佳化(如版面的非同步配置)
在性能提升的同時,也會造成一些麻煩,就是比較難以自我掌控狀況

在WPF裡面的UIElement提供了Measure和Arrange
讓程式開發者可以自主的控制版面配置

Measure提供的功能是讓系統知道這個控制項需要多大的空間
預設會遞迴的向他裡面所包含的子控制項問下去,之後再回報所需要的大小
Arrange提供的功能則是將Measure出來的位置擺到選定的位置上
這個位置是相對於父物件而言的,預設中同樣也會遞迴的將子控制項排好

而在使用這兩個函式的時候主要有兩種方式
一個是覆寫掉系統中預設的函式,讓這個元件依照你的設計來排版
這個方式主要用在寫自訂的控制項時,而且只能安排到你的下一層
而再向下的子控制項就只能依照預設的方式處理了(除非底層也被覆寫)

第二種方式則是直接呼叫,這種方法並不會真正的改變控制項的屬性
只是暫時的排版而已,常用在輸出圖檔的時候
可以參考在WPF中存圖檔的問題(RenderTargetBitmap)
呼叫Measure的時候要傳入一個Size的物件
傳入的大小如果比預設需求小,那之後WPF會自動發生一次重新測量及排列
所以在畫面上完全看不出來有被更改過
(但是如果在同一個函式中有輸出圖檔,該圖會依照改動的大小排列)
預設需求會包含物件的大小,以及設定的margin或是border thinkness等

呼叫Arrange的時候要傳入一個Rect,位置是相對於父物件的原點
將前一次Measuer的大小塞入這個Arrange的大小中
之後會依照該控制項原本就設定好的Margin等屬性自動排列

需要注意的有三點
第一,除了第一次呼叫Arrange之前須要先Measure之外(系統做的也算)
之後都可以只呼叫Arrange來重排而不需要重新測量大小,比如對齊
第二,只要呼叫了Measure就必須在後面接一個Arrange
否則系統也會自動加上一個預設的Arrange來依照此大小重排
第三,此兩個函式分別有各自的佇列(Queue)
但任何的Measure都會讓尚未處理的Arrange直接失效

--
參考資料
UIElement.Measure 方法
UIElement.Arrange 方法

沒有留言:

張貼留言