天天看點

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

無限限制

現在這裡有一些标記,起初看起來與前面的例子非常相似,但有很大的不同:

<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絕不能請求無限大小。

繼續閱讀