Silverlight学习笔记(3):Silverlight的界面布局

简介:
在上一篇中讲述了使用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 的简单例子:
< navigation:Page  x:Class ="SilverlightDemo1.StackPanelDemo"         
                      xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         
                      xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"         
                      xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"     
                      xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"     
                      mc:Ignorable ="d"     
                      xmlns:navigation ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"     
                      d:DesignWidth ="640"  d:DesignHeight ="480"     
                      Title ="StackPanelDemo Page" >     
         < StackPanel  Height ="100"  Name ="stackPanel1"  Width ="200"  Background ="Yellow" >     
                 < Button  Content ="按钮一"  Height ="23"  Name ="button1"  Width ="100"  />     
                 < Button  Content ="按钮二"  Height ="23"  Name ="button2"  Width ="200"  />     
                 < Button  Content ="按钮三"  Height ="23"  Name ="button3"  Width ="400"  />     
         </ StackPanel >     
</ navigation:Page >
这个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 的例子:
< navigation:Page  x:Class ="SilverlightDemo1.GridDemo1"         
                      xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         
                      xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"         
                      xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"     
                      xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"     
                      mc:Ignorable ="d"     
                      xmlns:navigation ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"     
                      d:DesignWidth ="400"  d:DesignHeight ="300"     
                      Title ="GridDemo1 Page" >     
         < Grid  x:Name ="LayoutRoot"  Background ="Pink" >     
                 < Grid.RowDefinitions >     
                         < RowDefinition  />     
                         < RowDefinition  Height ="200"  />     
                 </ Grid.RowDefinitions >     
                 < Grid.ColumnDefinitions >     
                         < ColumnDefinition  Width ="100"  />     
                         < ColumnDefinition  Width ="100"  />     
                         < ColumnDefinition  Width ="100"  />     
                         < ColumnDefinition  />     
                 </ Grid.ColumnDefinitions >     
                 < Button  Content ="按钮一"  Height ="23"  HorizontalAlignment ="Left"  Name ="button1" VerticalAlignment ="Center"  Width ="75"  Grid.Column ="0"  Grid.Row ="0"  />     
                 < Button  Content ="按钮二"  Grid.Column ="1"  Grid.Row ="0"  Height ="23"  HorizontalAlignment ="Center"  Name ="button2"  VerticalAlignment ="Top"  Width ="75"  />     
                 < TextBox  Grid.Column ="1"  Grid.Row ="1"  Height ="23"  HorizontalAlignment ="Center"  Name ="textBox1" VerticalAlignment ="Center"  Width ="80"  Text ="文本框"  />     
         </ Grid >     
</ navigation:Page >
它的显示效果如下:
当然Grid 也可以像HTML 中的Table 一样跨行或者跨列,这需要通过设置控件的RowSpan 或者ColumnSpan 属性,下面就是一个例子:
< navigation:Page  x:Class ="SilverlightDemo1.GridDemo1"         
                      xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         
                      xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"         
                      xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"     
                      xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"     
                      mc:Ignorable ="d"     
                      xmlns:navigation ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"     
                      d:DesignWidth ="400"  d:DesignHeight ="300"     
                      Title ="GridDemo1 Page" >     
         < Grid  x:Name ="LayoutRoot"  Background ="Pink" >     
                 < Grid.RowDefinitions >     
                         < RowDefinition  />     
                         < RowDefinition  Height ="200"  />     
                 </ Grid.RowDefinitions >     
                 < Grid.ColumnDefinitions >     
                         < ColumnDefinition  Width ="100"  />     
                         < ColumnDefinition  Width ="100"  />     
                         < ColumnDefinition  Width ="100"  />     
                         < ColumnDefinition  />     
                 </ Grid.ColumnDefinitions >     
                 < Button  Content ="按钮一"  Height ="220"  HorizontalAlignment ="Left"  Name ="button1"  Width ="75"  Grid.Column ="0"  Grid.Row ="0"  Grid.RowSpan ="2"  />     
                 < Button  Content ="按钮二"  Grid.Column ="1"  Grid.Row ="0"  Height ="23"  HorizontalAlignment ="Center"  Name ="button2"  VerticalAlignment ="Top"  Width ="75"  />     
                 < TextBox  Grid.Column ="1"  Grid.Row ="1"  Grid.ColumnSpan ="2"  Height ="23"  Name ="textBox1"  VerticalAlignment ="Center"  Width ="80"  Text ="文本框"  />     
                 < Button  Content ="按钮三"  Grid.Column ="2"  Height ="23"  HorizontalAlignment ="Left"  Name ="button3"  VerticalAlignment ="Top"  Width ="75"  />     
                 < Button  Content ="按钮四"  Grid.Column ="3"  Grid.Row ="1"  Height ="23"  HorizontalAlignment ="Left" Name ="button4"  VerticalAlignment ="Top"  Width ="75"  />     
         </ Grid >     
</ navigation:Page >
它的显示效果如下:
Canvas 布局用法
相比Grid Grid 的布局方式来说,Canvas 提供了另外一种途径来布置我们的控件,它采用了我们比较熟悉的利用坐标的方式的,在使用Canvas 布局时可以设置每个控件Top Left 属性,也就是设置控件距离它所在的容器的距离,下面就是一个例子:
< navigation:Page  x:Class ="SilverlightDemo1.CanvasDemo1" 
                      xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
                      xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"    
                      xmlns:d ="http://schemas.microsoft.com/expression/blend/2008" 
                      xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                      mc:Ignorable ="d" 
                      xmlns:navigation ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
                      d:DesignWidth ="640"  d:DesignHeight ="480" 
                      Title ="CanvasDemo1 Page" > 
         < Canvas  Height ="240"  Name ="canvas1"  Width ="300"  Background ="Teal" > 
                 < Button  Canvas.Left ="40"  Canvas.Top ="161"  Content ="登录"  Height ="23"  Name ="button1"  Width ="75"  /> 
                 < TextBlock  Canvas.Left ="40"  Canvas.Top ="56"  Height ="23"  Name ="textBlock1"  Text ="用户名"  /> 
                 < TextBlock  Canvas.Left ="40"  Canvas.Top ="102"  Height ="23"  Name ="textBlock2"  Text ="密码"  /> 
                 < Button  Canvas.Left ="183"  Canvas.Top ="161"  Content ="取消"  Height ="23"  Name ="button2"  Width ="75" /> 
                 < TextBox  Canvas.Left ="138"  Canvas.Top ="56"  Height ="23"  Name ="textBox1"  Width ="120"  /> 
                 < PasswordBox  Canvas.Left ="138"  Canvas.Top ="102"  Height ="23"  Name ="passwordBox1"  Width ="120"  /> 
         </ Canvas > 
</ navigation:Page >
它的显示效果如下:
在代码中我们对用户名所对应的文本框的设置是:
< TextBox  Canvas.Left ="138"  Canvas.Top ="56"  Height ="23"  Name ="textBox1"  Width ="120"  />
于是就会在距离Canvas 顶部56 、左边138 处显示一个高度为23 、宽度为120 的文本框。
布局的综合使用
虽然在XAML 中只能有一个顶级元素,但是这并不意味着在一个界面中只使用一种界面布局,我们完全可以在外层布局中嵌套内层布局,就像我们在HTML Table 中再次嵌套Table 一样,下面是一个简单的例子:
< navigation:Page  x:Class ="SilverlightDemo1.Graphics"         
                      xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         
                      xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"         
                      xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"     
                      xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"     
                      mc:Ignorable ="d"     
                      xmlns:navigation ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"     
                      d:DesignWidth ="800"  d:DesignHeight ="600"     
                      Title ="Chapter10 Page" >     
         < StackPanel  Width ="800"  Height ="600"  Orientation ="Vertical" >     
                 < Canvas  Width ="800"  Height ="200"  Background ="White" >     
                         < Canvas.Resources >     
                                 < Storyboard  x:Name ="myStroryboard" >     
                                         < DoubleAnimation  Storyboard.TargetName ="myTransform" Storyboard.TargetProperty ="Angle"     
                                                                          From ="0"  To ="360"  Duration ="0:0:5"  RepeatBehavior ="Forever" />     
                                 </ Storyboard >     
                         </ Canvas.Resources >     
                         < Image  Canvas.Left ="50"  Canvas.Top ="50"  Height ="100"  Name ="image01"  Stretch ="Fill" Width ="100"  Source ="image/15.jpg"  MouseEnter ="Image_MouseEnter"  MouseLeave ="Image_MouseLeave" >     
                                 < Image.RenderTransform >     
                                         < RotateTransform  x:Name ="myTransform"  Angle ="15"  CenterX ="50"  CenterY ="50" > </ RotateTransform >     
                                 </ Image.RenderTransform >     
                         </ Image >     
                         < Image  Canvas.Left ="350"  Canvas.Top ="0"  Height ="100"  Name ="image02"  Stretch ="Fill" Width ="100"  Source ="image/15.jpg" >     
                         </ Image >     
                         < Image  Canvas.Left ="350"  Canvas.Top ="0"  Height ="100"  Name ="image03"  Stretch ="Fill" Width ="100"  Source ="image/15.jpg"  Opacity ="0.8" >     
                                 < Image.RenderTransform >     
                                         < TransformGroup >     
                                         < ScaleTransform  ScaleY ="-0.75" > </ ScaleTransform >     
                                         < TranslateTransform     Y ="180"  X ="30" > </ TranslateTransform >     
                                                 < SkewTransform  AngleX ="-15" > </ SkewTransform >     
                                         </ TransformGroup >     
                                 </ Image.RenderTransform >     
                                 < Image.OpacityMask >     
                                         < LinearGradientBrush  StartPoint ="0.5,0.0"  EndPoint ="0.5,1.0" >     
                                                 < GradientStop  Offset ="0.0"  Color ="#00000000" > </ GradientStop >     
                                                 < GradientStop  Offset ="1.0"  Color ="#FF000000" > </ GradientStop >     
                                         </ LinearGradientBrush >     
                                 </ Image.OpacityMask >     
                         </ Image >     
                 </ Canvas >     
                 < Canvas  Width ="800"  Height ="200" >     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image31"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg"  />     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image32"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg" >     
                                 < Image.RenderTransform >     
                                         < RotateTransform  Angle ="15"  CenterX ="0"  CenterY ="0" > </ RotateTransform >     
                                 </ Image.RenderTransform >     
                         </ Image >     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image33"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg" >     
                                 < Image.RenderTransform >     
                                         < RotateTransform  Angle ="30"  CenterX ="50"  CenterY ="300" > </ RotateTransform >     
                                 </ Image.RenderTransform >     
                         </ Image >     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image34"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg" >     
                                 < Image.RenderTransform >     
                                         < RotateTransform  Angle ="45"  CenterX ="0"  CenterY ="50" > </ RotateTransform >     
                                 </ Image.RenderTransform >     
                         </ Image >     
                 </ Canvas >     
                 < Canvas  Width ="800"  Height ="200" >     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image1"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg"  />     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image2"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg" >     
                                 < Image.RenderTransform >     
                                         < RotateTransform  Angle ="15" > </ RotateTransform >     
                                 </ Image.RenderTransform >     
                         </ Image >     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image3"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg" >     
                                 < Image.RenderTransform >     
                                         < RotateTransform  Angle ="30" > </ RotateTransform >     
                                 </ Image.RenderTransform >     
                         </ Image >     
                         < Image  Canvas.Left ="100"  Canvas.Top ="10"  Height ="100"  Name ="image4"  Stretch ="Fill" Width ="200"  Source ="image/14.jpg" >     
                                 < Image.RenderTransform >     
                                         < RotateTransform  Angle ="40" > </ RotateTransform >     
                                 </ Image.RenderTransform >     
                         </ Image >     
                 </ Canvas >     
         </ StackPanel >     
</ navigation:Page >
它的显示效果如下:
总结:本篇主要讲述了Silverlight 中几种常见的布局:StackPanel 可以将控件按行或者按列布局,这是一种比较简单的布局方式;Grid 可以采用类似于HTML Table 的方式布局,并且可以设置控件跨行或者跨列摆放;Canvas 控件采用类似于坐标定位的方式对控件进行布局。还有一些布局在本篇中没有讲述,读者朋友可以在学习时借鉴这些知识来学习,其实利用这些布局已经足够实现复杂的界面了。














本文转自周金桥51CTO博客,原文链接: http://blog.51cto.com/zhoufoxcn/404352  ,如需转载请自行联系原作者



相关文章
|
索引 Windows
一起谈.NET技术,Silverlight 游戏开发小技巧:实现街霸4的选人界面
  上一篇只是一个引子,用来说明Projection的基本操作,游戏研发都是用这些小的基本功能慢慢组合出来,其实这一篇仍然是Projection,但是我们将会做一个比较复杂的应用使用silverlight的Projection,玩过街霸4,可能对它的选人界面印象深刻,但是做起来却不容易,因为要请美术...
942 0

热门文章

最新文章