在上一篇中讲述了使用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控件采用类似于坐标定位的方式对控件进行布局。还有一些布局在本篇中没有讲述,读者朋友可以在学习时借鉴这些知识来学习,其实利用这些布局已经足够实现复杂的界面了。
下一篇将讲述常用控件的学习。
周公(zhoufoxcn)
2010-10-11

转载于:https://www.cnblogs.com/zhoufoxcn/archive/2010/10/11/2515619.html

Silverlight学习笔记(3):Silverlight的界面布局相关推荐

  1. SilverLight学习笔记--建立Silverlight自定义控件(1)--外观设计

    Silverlight 2 以丰富且强大可靠的控件模型闻名,该模型是平台中包括的控件和第三方控件包的基础.您也可以使用此控件模型构建自己的控件.   在了解如何为新平台编写自定义控件时,我经常先复制一 ...

  2. SilverLight学习笔记--建立Silverlight自定义控件(5)--绑定动画效果

    有了上述的基础,我们进一步完善我们的自定义控件,在此我们将创建Storyboard和前面的添加事件处理方法为我们的自定义控件加上动画效果.   1.首先,在MyDesignButton项目中进一步完善 ...

  3. SilverLight学习笔记--关于Silverlight资源文件(如:图片)的放置位置及其引用

    Silverlight中有许多资源文件,例如:图片,音频.视频,甚至XML和XAML等非执行数据文件,在Silverlight中根据资源所处位置的不同而有所区别.    资源文件可分布在我们Silve ...

  4. duilib 子窗口位置_Duilib学习笔记《02》— 界面布局

    2. 简单空白窗体界面 此处以创建一个简单的空白的灰色背景窗体为例.对应的XML布局文件对应的也就很简单.如下: 1<?xml version="1.0" encoding= ...

  5. Python tkinter 学习笔记(3) -- 界面布局1(grid和pack)

    Python tkinter 学习笔记(1)-- 第一个窗口之HelloWorld 教程 Python tkinter 学习笔记(2)-- 控件.组件(一) Tkinter 界面布局(grid\pac ...

  6. Silverlight学习笔记(一)——Silverlight够酷吗?

    2007年底,微软推出了Silverlight1.0,在RIA领域小试牛刀.如今,Silverlight的成长速度已经超过了人们当初的想象.其一体化的编程方式.与JavaScript和Asp.Net的 ...

  7. SilverLight学习笔记--Silverlight中WebRequest通讯

    本文我们学习如何使用WebRequest类实现客户端和服务器端的通讯.      本例处理过程:在客户端,我们在文本框中输入任意文本,然后用POST方法向服务器端传递信息,服务器端收到从客户端传来的信 ...

  8. SilverLight学习笔记--Silverlight之数据绑定初探

    数据绑定(Data Binding)是用户界面UI和业务对象或其它数据提供者(data provider)的连接.用户界面对象称为目标,数据提供者成为数据源.   数据绑定帮助隔离应用程序的用户界面层 ...

  9. SilverLight学习笔记--如何在xaml文件中操作用户在后台代码定义的类(2)--示例篇:创建一个登录控件(原创)(转载本文请注明出处)...

    本文将示例如何运用前篇所写知识来建立一个用户自定义的登录控件.此控件界面非常简单,主要涉及的知识点是:   如何创建用户控件(包括对此控件的自定义事件和属性的编写,此处我们将创建一个名为LoginBo ...

  10. SilverLight学习笔记--Silverlight中WebService通讯

    本文我们学习如何在Silverlight中使用WebService进行通讯. 新建项目Silverlight应用程序,命名为:SLWebService. 在服务器端我们需要做两项目工作: 1.在Web ...

最新文章

  1. 彻底搞懂Nginx的五大应用场景
  2. sharepoint开机启动禁止
  3. SQL基础使用入门(二): DML语句和DCL语句
  4. Python 高级网络操作 - Python Advanced Network Operations
  5. Lua字符串库中的几个重点函数介绍
  6. [源码和文档分享]基于JAVA的即时通信软件
  7. c matlab 引擎调用,【MATLAB与C的混合编程】之【C程序调用Matlab计算引擎】(1)
  8. python怎么编辑文件_关于python:如何在Google Colab中编辑和保存文本文件(.py)?
  9. VS中项目的循环引用的问题
  10. JAVA 入门教程 2
  11. 推荐|10 款好用的远程管理工具
  12. android系统佳明app,佳明garmin运动手表app
  13. vb6集成ad登录共享文件_肇庆学院校园网WiFi认证自动登录指南
  14. 简易水下航行器舵控arduino,蓝牙通讯
  15. pdfjs转图片_Vue项目pdf(base64)转图片
  16. iphone及ipad屏幕尺寸参考
  17. HTML实现banner图切换
  18. 2022-02-13 机器学习基本概念
  19. 外卖商家入驻选择类目(JS数组)
  20. 儿童编程c语言_5种最适合儿童的编程语言

热门文章

  1. javascript --- event loop
  2. php基于数组的分页实现
  3. Hadoop系列(三)MapReduce Job的几种提交运行模式
  4. Excel使用控件创建动态地图图表
  5. 奉献给你:《Visual C# 2005程序开发与界面设计秘诀》
  6. halcon edges_sub_pix算子
  7. 创建一个最简单的imgui测试用例
  8. 【pyinstaller打包pyqt5编写的项目为exe(脱离环境可运行)】
  9. AD20学习笔记5---PCB设计规则设置及PCB手工布线
  10. C++11系列学习之七---------初始化列表