Silverlight 中使用不同面板进行布局的效果比较

      本文通过一个实例程序,比较Silverlight中应用面板控件Canvas,StackPanel,DockPanel,WrapPanel,Grid,VirtualizingStackPanel ,ViewBox来布局时,它们产生的效果异同。
一、不同面板的布局效果

 

二、源代码

 源代码下载

< UserControl xmlns:toolkit = " http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit "   xmlns:sdk = " http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk "   x:Class = " PanelLayout.MainPage "
    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 "
    d:DesignHeight
= " 300 "  d:DesignWidth = " 800 " >

    
< Grid x:Name = " LayoutRoot "  Background = " White "  ShowGridLines = " True " >

        
< Grid.RowDefinitions >
            
< RowDefinition Height = " 50 " />
            
< RowDefinition Height = " 50* " />
        
</ Grid.RowDefinitions >
        
< Grid.ColumnDefinitions >
            
< ColumnDefinition Width = " 160* " />
            
< ColumnDefinition Width = " 160* " />
            
< ColumnDefinition Width = " 160* " />
            
< ColumnDefinition Width = " 160* " />
            
< ColumnDefinition Width = " 160* " />
        
</ Grid.ColumnDefinitions >
        
< sdk:Label Grid.Row = " 0 "  Grid.Column = " 0 "  HorizontalContentAlignment = " Center "  Content = " Canvas " />
        
< Canvas Grid.Row = " 1 "  Grid.Column = " 0 " >
            
< Button Background = " Red " > Left = 0 , Top = 0 </ Button >
            
< Button Canvas.Left = " 18 "  Canvas.Top = " 18 "
            Background
= " Orange " > Left = 18 , Top = 18 </ Button >
        
</ Canvas >
        
        
< sdk:Label Grid.Row = " 0 "  Grid.Column = " 1 "  HorizontalContentAlignment = " Center "  Content = " StackPanel " />
        
< StackPanel Grid.Row = " 1 "  Grid.Column = " 1 "  FlowDirection = " LeftToRight "  VerticalAlignment = " Center " >
            
< Button  Background = " Red " > 1 </ Button >
            
< Button  Background = " Orange " > 2 </ Button >
            
< Button  Background = " Yellow " > 3 </ Button >
            
< Button  Background = " Lime " > 4 </ Button >
            
< Button Background = " Aqua " > 5 </ Button >
        
</ StackPanel >

        
< sdk:Label Grid.Row = " 0 "  Grid.Column = " 2 "  HorizontalContentAlignment = " Center "  Content = " DockPanel " />
        
< toolkit:DockPanel  Grid.Row = " 1 "  Grid.Column = " 2 "   VerticalAlignment = " Center " >
            
< Button  Background = " Red " > 1 </ Button >
            
< Button  Background = " Orange " > 2 </ Button >
            
< Button  Background = " Yellow " > 3 </ Button >
            
< Button  Background = " Lime " > 4 </ Button >
            
< Button Background = " Aqua " > 5 </ Button >
        
</ toolkit:DockPanel >



        
< sdk:Label Grid.Row = " 0 "  Grid.Column = " 3 "  HorizontalContentAlignment = " Center "  Content = " WrapPanel " />
        
< toolkit:WrapPanel Grid.Row = " 1 "  Grid.Column = " 3 "   VerticalAlignment = " Center " >

            
< Button  Background = " Red " > 1 </ Button >
            
< Button  Background = " Orange " > 2 </ Button >
            
< Button  Background = " Yellow " > 3 </ Button >
            
< Button  Background = " Lime " > 4 </ Button >
            
< Button Background = " Aqua " > 5 </ Button >
        
</ toolkit:WrapPanel >

  
        
< sdk:Label Grid.Row = " 0 "  Grid.Column = " 4 "  HorizontalContentAlignment = " Center "  Content = " Grid " />
        
< Grid Grid.Row = " 1 "  Grid.Column = " 4 " >
            
< Grid.RowDefinitions >
                
< RowDefinition Height = " 20* " />
                
< RowDefinition Height = " 20* " />
                
< RowDefinition Height = " 20* " />
                
< RowDefinition Height = " 20* " />
            
</ Grid.RowDefinitions >
            
< Grid.ColumnDefinitions >
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
            
</ Grid.ColumnDefinitions >
        
            
< Button Grid.Row = " 1 "  Grid.Column = " 1 "  Grid.RowSpan = " 2 "  Grid.ColumnSpan = " 3 "  Background = " Green "   BorderBrush = " Red "  BorderThickness = " 5 "   ></ Button >
        
</ Grid >

        
< sdk:GridSplitter Grid.Row = " 1 "  Grid.Column = " 0 "  Width = " 10 "  Background = " Lime " />
        
< sdk:GridSplitter Grid.Row = " 1 "  Grid.Column = " 1 "  Width = " 10 "  Background = " Lime " />
        
< sdk:GridSplitter Grid.Row = " 1 "  Grid.Column = " 2 "  Width = " 10 "  Background = " Lime " />
        
< sdk:GridSplitter Grid.Row = " 1 "  Grid.Column = " 3 "  Width = " 10 "  Background = " Lime " />
    
</ Grid >
</ UserControl >

 

三、通过分析它们的特点,得出它们适合应用的场合。

 

不同布局面板的特点:
1、Canvas
      Canvas 使您可以进行 (x,y) 定位,这与 GDI 和 GDI+ 目前提供的功能类似。您还可以使用附加的属性Left,Top来控制

项的位置。
2、DockPanel
      DockPanel使您在停靠项时无需担心它们的确切 (x,y) 位置。
3、StackPanel 提供一个从左至右(水平)或从上至下(垂直)放置内容的堆栈模型。
      StackPanel的默认排列方式为Vertical(垂直),但是如果你想指定为Horizontal(水平),
      那么你可以使用属性Orientation="Horizontal"。

 

 如:  < StackPanel Grid.Row = " 1 "  Grid.Column = " 1 "  FlowDirection = " LeftToRight "  VerticalAlignment = " Center "  Orientation = " Horizontal " />

 4、WrapPanel
WrapPanel用于在水平方向或垂直方向顺序显示子元素,当到达边缘时,则本行不足以显示的子元素对象自动换到下一行顺序显示。

5、Grid
     Grid 提供一个允许进行行/网格定位的模型:
     可用 SharedSizeGroup 属性为多个对象指定共享的大小。
     例如,可使用该属性来指定两个按钮具有相同的宽度(即使它们通常具有不同的大小范围)。

< Border xmlns = " http://schemas.microsoft.com/winfx/avalon/2005 " >
< Grid LayoutTransform = " scale 2 "  ShowGridLines = " true "  IsSharedSizeScope = " true "  Height = " 80 " >
< ColumnDefinition Width = " 30 "   />
< ColumnDefinition Width = " Auto "  SharedSizeGroup = " Buttons "   />
< ColumnDefinition Width = " Auto "  SharedSizeGroup = " Buttons "   />
< RowDefinition  />
< Button Grid.Column = " 1 "  Margin = " 10 " > OK </ Button >
< Button Grid.Column = " 2 "  Margin = " 10 " > A very  long  cancel button </ Button >
</ Grid >

   可以指定元素使用Grid 的RowSpan,ColumnSpan来设置元素占用Grid的表格数量。效果如上图右边效果显示。

         < Grid Grid.Row = " 1 "  Grid.Column = " 4 " >
            
< Grid.RowDefinitions >
                
< RowDefinition Height = " 20* " />
                
< RowDefinition Height = " 20* " />
                
< RowDefinition Height = " 20* " />
                
< RowDefinition Height = " 20* " />
            
</ Grid.RowDefinitions >
            
< Grid.ColumnDefinitions >
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
                
< ColumnDefinition Width = " 20* " />
            
</ Grid.ColumnDefinitions >
 
< Button Grid.Row = " 1 "  Grid.Column = " 1 "  Grid.RowSpan = " 2 "  Grid.ColumnSpan = " 3 "  Background = " Green "   BorderBrush = " Red "  BorderThickness = " 5 "   >
                
< Button.Content >
                    
< Grid >
                        
< Grid.RowDefinitions >
                            
< RowDefinition ></ RowDefinition >
                            
< RowDefinition  ></ RowDefinition >
                        
</ Grid.RowDefinitions >
                        
< Image Source = " Images/note.png "   Grid.Row = " 0 " >
                        
</ Image >
                        
< TextBlock Text = " FRJ提醒 "  Grid.Row = " 1 "  VerticalAlignment = " Center "  HorizontalAlignment = " Center " >
                        
</ TextBlock >
                    
</ Grid >
                
</ Button.Content >
            
</ Button >

6、ViewBox

ViewBox 具有约束内容的大小以适应父面板的相反效果。这就提供了一种自动缩放效果。

以下示例中的文字,将根据窗口的大小,自动变大与缩小。

    <Grid x:Name="LayoutRoot" Background="White">
        <Border>
            <Viewbox>
                <TextBlock FontFamily="Global User Interface"> 人之初,性本善,性相近,习相远。苟不教,性乃迁,教之道,贵以专。</TextBlock>
            </Viewbox>
        </Border>     

    </Grid>

 

7、VirtualizingStackPanel
         将内容排列和虚拟化在一行上,方向为水平或垂直。      
         VirtualizingStackPanel在普通StackPanel的基础上,提供了”虚拟化”的功能。那什么是”虚拟化”呢?先来看一个场景,如果你有一堆基于项的数据,并且你只需要让其中一部分显示在界面上,但是如果你针对里面所有的数据创建界面元素,并显示你需要的元素,那么这将是及其耗时的。”虚拟化”就是用于解决这个问题,它可以只创建你需要显示的数据的界面元素。即 “虚拟化”是指一种技术,通过该技术,可根据屏幕上所显示的项来从大量数据项中生成user interface (UI) 元素的子集。
         VirtualizingStackPanel中的项只有在数据绑定的状态下,才提供”虚拟化”,否则和普通的StackPanel没有区别。
        即仅当 StackPanel 中包含的项控件创建自己的项容器时,才会在该面板中发生虚拟化。 可以使用数据绑定来确保发生这一过程。 如果创建项容器并将其添加到项控件中,则与 StackPanel 相比,VirtualizingStackPanel 不能提供任何性能优势。
        应用示例:
        http://msdn.microsoft.com/zh-cn/library/system.windows.controls.virtualizingstackpanel.aspx
        下面的示例演示如何使用Extensible Application Markup Language (XAML) 绑定到 XML 数据源,并虚拟化 ListBox 元素中显示的项。 注意:IsVirtualizing 附加属性显式设置为 true。

 

  < Page xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "  
      xmlns:x
= " http://schemas.microsoft.com/winfx/2006/xaml "  
      WindowTitle
= " VirtualizingStackPanel Sample "  
      Height
= " 150 "
      VerticalAlignment
= " Top " >
    
< Page.Resources >
        
< XmlDataProvider x:Key = " Leagues "  Source = " Leagues.xml "  XPath = " Leagues/League " />

    
< DataTemplate x:Key = " NameDataStyle " >
      
< TextBlock Text = " {Binding XPath=@name} "  FontFamily = " Arial "  FontSize = " 12 "  Foreground = " Black " />
    
</ DataTemplate >

    
</ Page.Resources >
  
< Border HorizontalAlignment = " Left "  
          VerticalAlignment
= " Top "  
          BorderBrush
= " Black "  
          BorderThickness
= " 2 " >
       
< ScrollViewer >
      
< StackPanel DataContext = " {Binding Source={StaticResource Leagues}} " >
          
< TextBlock Text = " {Binding XPath=@name} "  FontFamily = " Arial "  FontSize = " 18 "  Foreground = " Black " />
              
< ListBox VirtualizingStackPanel.IsVirtualizing = " True "  
                       ItemsSource
= " {Binding XPath=Team} "  
                       ItemTemplate
= " {DynamicResource NameDataStyle} " />       
      
</ StackPanel >
      
</ ScrollViewer >
  
</ Border >     
</ Page >

下面的示例创建一个 ListBox,并将 VirtualizingStackPanel.VirtualizationMode 附加属性设置为 Recycling。

< StackPanel >

  
< StackPanel.Resources >
    
< src:LotsOfItems x:Key = " data " />
  
</ StackPanel.Resources >

  
< ListBox Height = " 150 "  ItemsSource = " {StaticResource data} "  
             VirtualizingStackPanel.VirtualizationMode
= " Recycling "   />

</ StackPanel >

下面的示例演示上例中所使用的数据。

public   class  LotsOfItems : ObservableCollection < String >
{
    
public  LotsOfItems()
    {
        
for  ( int  i  =   0 ; i  <   1000 ++ i)
        {
            Add(
" item  "   +  i.ToString());
        }
    }
}

 

     布局是任何用户界面子系统的基础服务之一,它涉及如何确定元素在窗口中的位置。设计 Windows Presentation Foundation 布局系统的目的是为灵活的可扩展模型提供支持,该模型针对内容进行优化,并且能够正确地处理数据、样式和控件。
     传统的应用程序平台(如 Win32)几乎没有布局的概念:控件放置在画布上的 (x,y) 坐标系中,并且开发人员需要手动提供对确定任何元素的原点和尺寸的支持(考虑窗口大小调整和显示器 DPI 设置)。另一方面,Windows Presentation Foundation 提供多种适合于内容并且在窗口内管理控件和项目位置的布局实现。
在 Windows Presentation Foundation 中,几乎可以使用任何元素作为其他元素的宿主。例如,Button 可按如下方式包含图像:

< Button Grid.Row = " 1 "  Grid.Column = " 1 "  Grid.RowSpan = " 2 "  Grid.ColumnSpan = " 3 "  Background = " Green "     BorderBrush = " Red "  BorderThickness = " 5 "   >
                
< Button.Content >
                    
< Grid >
                        
< Grid.RowDefinitions >
                            
< RowDefinition ></ RowDefinition >
                            
< RowDefinition  ></ RowDefinition >
                        
</ Grid.RowDefinitions >
                        
< Image Source = " Images/note.png "   Grid.Row = " 0 " >
                        
</ Image >
                        
< TextBlock Text = " FRJ提醒 "  Grid.Row = " 1 "  VerticalAlignment = " Center "  HorizontalAlignment = " Center " >
                        
</ TextBlock >
                    
</ Grid >
                
</ Button.Content >
            
</ Button >


      面板负责其子元素的布局。它们定义内容的大小和形状、对齐方式和边距。面板的子元素可以是诸如 TextBox 或 Button 这样的元素,也可以是另一个面板。
例如,DockPanel 可以包含 StackPanel 项调整大小以适应它们所包含的内容 — 这是一个重要的概念,因为它确保了应用程序的本地化不需要重新校准应用程序布局(因为不同语言的同一句子 — 例如“Auf Wiedersehen”与“Goodbye”— 具有不同的文本长度)。可用 HorizontalAlignment/VerticalAlignment 属性应用对齐方式,并且使用 Margin 属性指定边距。ScrollViewer 提供子元素内容的滚动视图;如果内容溢出可用的空间,则会显示一个滚动条并允许用户在内容区域周围移动。
例如:

<Border >

<ScrollViewer>     

<TextBlock FontSize="20" TextWrapping="Wrap" FontFamily="Global User Interface">

      人之初,性本善,性相近,习相远。苟不教,性乃迁,教之道,贵以专。

  昔孟母,择邻处,子不学,断机杼。窦燕山,有义方,教五子,名俱扬。

  养不教,父之过,教不严,师之惰。子不学,非所宜,幼不学,老何为?

  玉不琢,不成器,人不学,不知义。为人子,方少时,亲师友,习礼仪。

  香九龄,能温席,孝于亲,所当执。融四岁,能让梨,悌于长,宜先知。       

</TextBlock>  

</ScrollViewer>

</Border>

      布局协议是一个递归过程,它是某种形式的协商,目的是确保所有元素都基于其请求获得“公平”数量的空间。首先,将发生一个测量过程,其中,父元素询问子元素希望自己多大,而子元素用 DesiredSize 进行响应。然后,将发生排列过程,其中,父元素以 ActualSize 属性的形式告诉子元素它将有多大。在进行计算时,特殊值 Double.PositiveInfinity 意味着“适合于内容”。可通过重写面板的 MeasureOverride 和 ArrangeOverride 元素来处理这一问题。


         

 

 

posted on 2011-05-04 19:22 DotNet编程 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/furenjun/archive/2011/05/04/2036896.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值