原文地址:http://create.msdn.com/zh-CN/education/quickstarts/Layout_on_the_Screen
【譯者注:這篇文章是翻譯自微軟官方的WP7 QuickStart的第七篇,講述WP下的布局。部分內容加入了自己的理解和表達習慣。而翻譯此系列的主要目的一是為了練習英語,二是讓自己作為一個BI開發人員對WP7的開發有一個瞭解。部分翻譯不當的地方望各位高人指出批評指正】
Windows Phone下的Silverlight提供了一種靈活的布局方式來指定控制項在螢幕上的位置。此篇主要描述如何設計根據不同螢幕解析度自動大小的使用者介面。
主要包含以下內容
布局總覽
絕對布局
動態布局
Panel控制項
布局總覽
Windows Phone下Silverlight的布局,是處理對象大小和位置的過程。給一個視覺元素布局,需要將其放入Panel控制項或者其它容器控制項中。Silverlight提供了一些Panel控制項,比如Canvas,StackPanel和Grid,作為容器來定位和布置控制項。
Windows Phone的Silverlight布局系統支援絕對和動態布局。在絕對布局方式中,控制項的定義通過類似x/y的座標方式,比如Canvas。在動態布局方式中,使用者介面根據螢幕的解析度自動調整大小。
絕對布局
在絕對布局方式中,在布局面板中子項目通過指定其父元素中的位置座標的形式來實現布局。絕對布局的方式並沒有考慮到螢幕的大小。如果為了照顧到不同的螢幕解析度,可以為其不同的螢幕解析度單獨的去設計不同的頁面。
Windows Phone的Silverlight提供了Canvas來支援絕對方式的布局。預設情況下建立新Windows Phone程式項目的時候,根布局元素為Grid。如果要用絕對方式的布局,需要把Grid替換成Canvas。
在Canvas中布局,需要設定下面兩個屬性。在Visual Studio的設計檢視中,當把控制項拖拽到頁面上的時候這兩個屬性就被更新了。
Canvas.Left
Canvas.Top
動態布局
在動態布局中,使用者介面會根據螢幕解析度的不同呈現不同的效果。子項目在父元素中通過指定如何布置和如何自動換行。比如,可以在面板中布置控制項並且指定他們如何自定橫向自動切換。要用到自動的或者根據比例的大小,需要設定其Height和Width屬性。
設定Height和Width屬性為Auto。當在Grid布局中使用這些值的時候,控制項會填充滿其容器。Auto屬性在Grid和StackPanel中都是支援的。
對於包含文本的控制項,不要設定其Height和Width屬性,設定MinWidth和MinHeight屬性。這樣會避免出現常值內容由於容器大小問題而顯示不全的情況。
如果要在Grid中按比例設定RowDefinition和ColumnDefinition,可以使用比例方式的Height和Width值。比如,如果要設定一個列是另一個列的五倍寬,可以分別對兩列的ColumnDefinition屬性的Width設定成*和5*。
Auto和星形符號調整大小
Auto用來讓其填充滿容器,即使內容的大小是可變的。星型模式用來根據比例分配Grid裡的行和列。比如,如果有四個列,按照下面的設定其中的值。
Column_1
Auto-列會自動填滿地區。
Column_2
*-列被分配完之後,這個列的寬度就是Column_4的一半。
Column_3
Auto-同Column_1
Column_4
2*-這個列的寬度會是列Column_2的一倍。
面板控制項
Windows Phone的Silverlight下內建的面板有Canvas,StackPanel和Grid。
Canvas
Canvas使其內部的元素通過類似座標的方式定位。Canvas適合用在包含的UI元素不需要移動或者改變的情況。
可以通過Canvas裡控制項的座標來實現定位。這個座標就是通過Canvas.Left和Canvas.Top來實現的。Canvas.Left通過設定對象距離Canvas容器左面邊界的距離,Canvas.Top指定距離Canvas頂部邊界的距離。
下面代碼示範的是一個距離螢幕左端30像素,頂端200像素的矩形。
XAML
<Canvas Background="Transparent">
<Rectangle Canvas.Left="30" Canvas.Top="200"
Fill="red" Width="200" Height="200" />
</Canvas>
效果如:
StackPanel
StackPanel控制項可以將其內部的元素以線性方式橫向或者縱向排布。通過Orientation屬性指定子項目是以橫向還是縱向排列,預設的屬性為Vertical。
下面示範XAML的StackPanel子項目的縱向排列。
XAML
<StackPanel Margin="20">
<Rectangle Fill="Red" Width="50" Height="50" Margin="5" />
<Rectangle Fill="Blue" Width="50" Height="50" Margin="5" />
<Rectangle Fill="Green" Width="50" Height="50" Margin="5" />
<Rectangle Fill="Purple" Width="50" Height="50" Margin="5" />
</StackPanel>
運行效果如:
Grid
Grid是最靈活的布局面板,支援多行和多列的方式布局。可以通過Grid.RowDefinitions和Grid.ColumnDefinitions屬性來設定Grid裡的行列資訊。其內部的元素可以通過Grid.Column和Grid.Row屬性定義定位到Grid的哪一行哪一列。內容也可以通過RowSpan和ColumnSpan的方式定義跨行和跨列。
Grid裡的子項目根據XAML和代碼的順序依次顯示在介面上,這樣子項目就可以使用相同的座標系統。可以參考ZIndex屬性。
下面的XAML代碼建立了一個三行兩列的Grid。第一行和第三行的高度以撐滿布局的方式填充,第二行的高度則分配成了剩餘可用的高度。列的寬度是均分的。
XAML
<Grid ShowGridLines="True" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Text="1st row 1st column" TextWrapping="Wrap" Grid.Column="0" Grid.Row="0" />
<TextBox Text="3rd row 1st column" TextWrapping="Wrap" Grid.Column="0" Grid.Row="2" />
<Button Content="1st row 3rd column" FontSize="17" Grid.Column="1" Grid.Row="0" />
<Button Content="3rd row 2nd column" FontSize="17" Grid.Column="1" Grid.Row="2" />
</Grid>
效果如所示:
如果對布局的需求比較複雜,並且Canvas, StackPanel和Grid都不能滿足要求,可以嘗試建立一個自訂的面板來實現子面板裡的元素布局行為。具體的實現方法是繼承Panel類並且重寫其中的MeasureOverride和ArrangeOverride方法。
【譯者註:這部分跟傳統的Silverlight是完全相同的了。】