原文地址: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是完全相同的了。】