在上一篇中讲述了使用VS2010开发Silverlight的一些基础知识,并且讲述了Silverlight的部署和代码安全知识,这一篇主要是讲述如何在Silverlight中摆放界面元素。
记得早年前我还在学习Java的时候,当时有两种开发Java SE的方法,一种是使用JCreator或者JBuilder之类的IDE开发(现在这二者都几乎没人用了,流行的是Eclipse或者NetBeans);一种是使用Visual J++开发。使用前一种方法开发的Java程序可以多种操作系统平台上运行,不过界面布局比较麻烦,什么CardLayout、FlowLayout、BorderLayout、GridBagLayout、GridLayout等等,开发一个复杂的界面需要开发人员对各种布局类都有所了解;使用Visual J++开发的话可以使用XY坐标来定位元素,相对来说容易多了,不过这种开发的Java软件并不是严格意义上的Java软件,它只能在Windows平台上运行。Java从出现到现在,在Java EE和Java ME上都相对比较成功,而唯独在Java SE上表现不佳,不知道跟它难以使用的界面布局有关系。
布局概述
在上一篇提到了XAML语言,它适用于在WPF和Silverlight中进行界面布局的标记语言,它是一种有特定要求的XML语言,从某种意义上来说,我觉得它和XHTML走得更近一些:首先它们都是有特定格式的XML语言,其次它们都是用于界面布局。除此之外,在XAML语言中还有一个特点,那就是每一个元素都代表着一个Silverlight中的类,并且在XAML中只能有一个顶级元素。因此在进行WPF和Silverlight开发时不能绕开的一个问题就是界面布局,在Silverlight中常见的界面布局类有Canvas、Grid和StackPanel。
Canvas、Grid和StackPanel其实都是继承自System.Windows.Controls.Panel的类,它们的继承层次关系如下图:
Panel类有如下比较常见的属性:
Background:用于填充 Panel 的边框之间的区域的 Brush。
Children:此 Panel 的子元素的 UIElementCollection。
Height:元素的建议高度。
HorizontalAlignment:在父元素(如面板或项控件)中构成此元素时应用于此元素的水平对齐特征。
MaxHeight:元素的最大高度约束,MaxHeight的默认值是PositiveInfinity(正无穷大)。
MaxWidth:元素的最大宽度约束,MaxWidth的默认值是PositiveInfinity(正无穷大)。
MinHeight:元素的最小高度约束,MinHeight的默认值分别是Auto(自动调整)。
MinWidth:元素的最小宽度约束,MinWidth的默认值分别是Auto(自动调整)。
VerticalAlignment:在父元素(如面板或项控件)中组合此元素时应用于此元素的垂直对齐特征。
Width:元素的宽度。
可以看出在这里存在着Height、MaxHeigh、MinHeight及Width、MaxWidth、MinWidth这么两组与高度和宽度相关的属性,这的确让初学的人有些模糊。这些值之间存在着什么样的关系呢?拿Width、MaxWidth、MinWidth来说,它们存在的关系如下:如果这三个值之间存在冲突,则应用程序确定宽度的实际顺序是:首先必须采用 MinWidth;然后采用 MaxWidth;最后,如果这些值中的每个值都在限制之内,则采用 Width。为什么对于Width或者Height会出现这么三个属性呢?这是跟编程有一定的关系,假如我们在一个布局容器中水平放置了三个按钮,每个按钮的宽度是60像素,即使不考虑这三个按钮之间的间隙显示这三个按钮的宽度至少需要180像素,在默认情况下Width、MaxWidth、MinWidth的默认值分别是Auto(自动调整)、PositiveInfinity(正无穷大)、0.0,这样一来按照上面的规则会采取自动调整的方式。
StackPanel布局用法
StackPane是上面提到的几种布局中最简单的一种布局方式,它在一行或者一列中显示所有的子控件,默认情况下它是在一列中显示所有元素的,不过可以通过设置它的Orientation 属性为Horizontal以指示在一行中显示所有元素。
下面是一个使用StackPanel的简单例子:
这个Page的显示效果如下:
在上面的代码中我们设置StackPanel的Width为200,没有设置MaxWidth、MinWidth的值,最终实际显示宽度为200,因为此时MaxWidth和MinWidth都采用了默认值,因为这这三个值有冲突但是都在限制(没有找到具体对限制的定义,周公推测为MinWidth≤Width≤MaxWidth,如果您觉得周公的推测不正确,请告知以免误导大家,谢谢)之内,所以最终实际宽度为200。
如果设置StackPanel的Width、MaxWidth、MinWidth分别为200、400、100,最终实际显示宽度仍为200,原因同上,如下图所示:
如果设置StackPanel的Width、MaxWidth、MinWidth分别为200、100、100,最终实际显示宽度为100,这里MaxWidth和MinWidth都是100,而Width却是200不在限制之内,所以最终显示宽度为MinWidth设置的宽度,如下图所示:
如果设置StackPanel的Width、MaxWidth、MinWidth分别为200、400、500,最终实际显示宽度为500,这里MaxWidth和MinWidth分别是400和500,而Width却是200不在限制之内,所以最终显示宽度也为MinWidth设置的宽度,如下图所示:
Grid布局用法
Grid布局是Silverlight一种比较复杂的布局,它有点像我们HTML中的Table元素,将空间划分为行和列组成的单元格,在每个单元格中可以放置其它元素,下面是一个使用Grid的例子:
它的显示效果如下:
当然Grid也可以像HTML中的Table一样跨行或者跨列,这需要通过设置控件的RowSpan或者ColumnSpan属性,下面就是一个例子:
它的显示效果如下:
Canvas布局用法
相比Grid和Grid的布局方式来说,Canvas提供了另外一种途径来布置我们的控件,它采用了我们比较熟悉的利用坐标的方式的,在使用Canvas布局时可以设置每个控件Top和Left属性,也就是设置控件距离它所在的容器的距离,下面就是一个例子:
它的显示效果如下:
在代码中我们对用户名所对应的文本框的设置是:
<TextBox Canvas.Left="138" Canvas.Top="56" Height="23" Name="textBox1" Width="120" />
于是就会在距离Canvas顶部56、左边138处显示一个高度为23、宽度为120的文本框。
布局的综合使用
虽然在XAML中只能有一个顶级元素,但是这并不意味着在一个界面中只使用一种界面布局,我们完全可以在外层布局中嵌套内层布局,就像我们在HTML的Table中再次嵌套Table一样,下面是一个简单的例子:
它的显示效果如下:
总结:本篇主要讲述了Silverlight中几种常见的布局:StackPanel可以将控件按行或者按列布局,这是一种比较简单的布局方式;Grid可以采用类似于HTML中Table的方式布局,并且可以设置控件跨行或者跨列摆放;Canvas控件采用类似于坐标定位的方式对控件进行布局。还有一些布局在本篇中没有讲述,读者朋友可以在学习时借鉴这些知识来学习,其实利用这些布局已经足够实现复杂的界面了。
下一篇将讲述常用控件的学习。
周公(zhoufoxcn)
2010-10-11