• 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 元素来处理这一问题。


             

  • 相关阅读:
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    2013551822第一次作业
    第八次作业
    第七次作业
    第六次作业
    第五次作业
    第四次作业
  • 原文地址:https://www.cnblogs.com/furenjun/p/2036896.html
Copyright © 2020-2023  润新知