第二十六章:自定義佈局(四)

無限約束
現在這裏有一些標記,起初看起來與前面的例子非常相似,但有很大的不同:

<ContentPage __ Padding="20">
    <StackLayout>
        <Label Text="Sample text" />
        __
    </StackLayout>
</ContentPage>

ContentPage仍然使用參數(0,0,360,640)進行初始佈局調用,而LayoutChildren覆蓋的參數是(20,20,320,600)。它有一個孩子,StackLayout。 StackLayout具有LayoutOptions.Fill的Horizo​​ntalOptions和VerticalOptions的默認設置,這意味着StackLayout可以相對於ContentPage定位,佈局調用爲(20,20,320,600)。
這導致StackLayout獲得一個參數爲(0,0,320,600)的LayoutChildren調用。 StackLayout如何確定其子女的大小和位置?
正如我們從第4章開始使用StackLayout所知道的那樣,垂直StackLayout爲其子級提供與其自身相同的水平大小,但是根據子級需要提供垂直大小。這意味着StackLayout必須在調用Layout之前在其所有子節點上調用GetSizeRequest。但是它應該用GetSizeRequest調用指定什麼約束?
最初的衝動可能是StackLayout在其子節點上調用GetSizeRequest,其約束條件反映了它自己的大小(320,600)。但那不對。 StackLayout不會將其子項限制在自己的高度。它允許孩子成爲他們需要的任何高度。這意味着高度約束實際上應該是無限的。
這是事實。 StackLayout在其子節點上調用GetSizeRequest,其高度爲(320,∞),或者就.NET而言(320,Double.PositiveInfinity)。
這很重要:傳遞給GetSizeRequest和OnSizeRequest的約束可以從0到Double.PositiveInfinity。 但是,GetSizeRequest和OnSizeRequest永遠不會通過返回SizeRequest值並將屬性設置爲Double.PositiveInfinity來請求無限維。
讓我們嘗試另一種常見的佈局模式:

<ContentPage __ Padding="20">
    <ScrollView>
        <StackLayout>
            <Label Text="Sample text" />
            __
        </StackLayout>
    </ScrollView>
</ContentPage>

像往常一樣,ContentPage使用邊界矩形(0,0,360,640)調用Layout,並調用其參數爲(20,20,320,600)的LayoutChildren方法。 ScrollView具有LayoutOptions.Fill的默認Horizo​​ntalOptions和VerticalOptions設置,因此頁面不需要知道ScrollView的大小。該頁面簡單地調用ScrollView的Layout方法,其邊界矩形爲(20,20,320,600)。
然後ScrollView調用其LayoutChildren方法,參數爲(0,0,320,600)。它需要確定其子項的大小(StackLayout),因此它調用StackLayout的GetSizeRequest方法。約束應該是什麼?
在一般情況下,StackLayout的高度將大於ScrollView的高度。這就是爲什麼你在可視樹中包含ScrollView的原因!如果要成功滾動其子項,ScrollView需要知道該高度。因此,ScrollView使用(320,Double.PositiveInfinity)的約束調用StackLayout的GetSizeRequest方法。這轉換爲使用相同的約束參數調用OnSizeRequest,StackLayout覆蓋並處理這些參數。
您還可以將無限約束視爲自動調整指示。垂直StackLayout請求具有無限高度約束的子大小以獲取子請求的高度。類似地,行高或行寬爲GridLength.Auto的Grid單元格的子節點將看到無限的heightConstraint或widthConstraint,或兩者。具有LayoutBounds高度或寬度Auto的AbsoluteLayout的子項也將看到無限的heightConstraint或widthConstraint。
有時,受約束和不受約束的詞語用於指代這些差異。當元素接收到具有非無限參數的GetSizeRequest方法的調用時,它會受到約束。該元素被約束爲特定大小。當一個元素調用GetSizeRequest並且一個或兩個參數等於Double.PositiveInfinity時,該元素是不受約束的。有時,部分約束這個術語用於引用帶有一個Double.PositiveInfinity參數的GetSizeRequest調用,而術語完全約束則表明兩個參數都不是無限的。
通過從Layout 派生編寫自己的自定義佈局類時,必須覆蓋OnSizeRequest和LayoutChildren方法,並且必須注意在某些情況下,OnSizeRequest的一個或兩個約束參數將爲Double.PositiveInfinity。 但是,OnSizeRequest絕不能請求無限大小。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章