• XAML学习笔记——Layout(二)


       本篇随笔将简单介绍两种基本的布局——Grid布局和VariableSizedWrapGrid布局。

      Grid布局

      顾名思义,Grid布局将布局容器以行和列的分割方法拆分成若干单元格,然后通过指定子元素所属单元格的行编号(Grid.Row)与列编号(Grid.Column)的方式将一个或多个子元素排列在指定的单元格中,从而以表格的形式排列子元素。从功能和设计方式上讲,Grid布局排列子元素的行为和HTML中的 table 类似,但是使用方式更加灵活。Grid布局在开发过程中多用于表单的开发设计,并且经常用于其他布局的父容器嵌套使用,如以后会介绍的SplitView、ViewBox布局等。

      定义行(Rows)和列(Columns)

      依据定义,我们想要搞定Grid布局最重要的就是搞定行和列。具体来讲包括行和列的添加以及行和列尺寸的相关定义。

      首先要根据需求确定Grid布局所需的行数与列数,Grid布局默认只包含一行一列,如果要添加其他的行和列就必须在Grid中的RowDefinitionsColumnDefinitions两个属性集合中分别添加相应数量的子元素,下面的代码展示了如何定义一个包含四行两列的Grid。

     1 <Grid>
     2     <Grid.RowDefinitions>
     3         <RowDefinition />
     4         <RowDefinition />
     5         <RowDefinition />
     6         <RowDefinition />
     7     </Grid.RowDefinitions>
     8     <Grid.ColumnDefinitions>
     9         <ColumnDefinition />
    10         <ColumnDefinition />
    11     </Grid.ColumnDefinitions>
    12 </Grid>

      确定好行和列的数量之后,我们就要为行和列的尺寸属性赋值。

      在实际开发中我们关心的是行的高度(Height)属性和列的宽度(Width)属性,以行高为例,有三种方式可以为其赋值,分别为:

    • Fixed 即此行高度为固定数值(据官方数据一个单位为1/96 英寸??)
    • Auto  此行的高度完全取决于其包含元素的高度。
    • Star (*)  按各行比例分配相应高度,举个例子就很容易明白了:
    1. 若将n行的高度都赋值为"*",那么每行的高度为n行所占总高度的1/n;
    2. 如果只有两行,第一行高度赋值为"3*"而第二行高度赋值为"5*",那么第一行就占两行总高度的3/8而第二行占5/8;
    3. 如果某些行的高度值以其他两种方式赋值,则不参与按比例赋值的计算;

      用同样的方法为列的宽度属性赋值,接着上面的例子将行和列的尺寸赋值后,代码如下:

     1 <Grid>
     2     <Grid.RowDefinitions>
     3         <RowDefinition Height="Auto" />
     4         <RowDefinition Height="Auto" />
     5         <RowDefinition Height="*" />
     6         <RowDefinition Height="28" />
     7     </Grid.RowDefinitions>
     8     <Grid.ColumnDefinitions>
     9         <ColumnDefinition Width="Auto" />
    10         <ColumnDefinition Width="200" />
    11     </Grid.ColumnDefinitions>
    12 </Grid>

       向Grid中添加元素

       放在Grid中的元素必须放在<Grid>开闭标签之间,通过为元素添加Grid.Column和Grid.Row属性的方式来确定元素的位置,两个属性的值分别为Grid的列索引号和行索引号(从0开始)。

        继续为上面的例子中添加几个控件,代码如下:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>
        <TextBlockGrid.Row="0" Grid.Column="0" Content="Name:"/>
        <TextBlockGrid.Row="1" Grid.Column="0" Content="E-Mail:"/>
        <TextBlock Grid.Row="2" Grid.Column="0" Content="Comment:"/>
        <TextBox Grid.Column="1" Grid.Row="0" Margin="3" />
        <TextBox Grid.Column="1" Grid.Row="1" Margin="3" />
        <TextBox Grid.Column="1" Grid.Row="2" Margin="3" />
        <Button Grid.Column="1" Grid.Row="3" HorizontalAlignment="Right" 
                MinWidth="80" Margin="3" Content="Send"  />
    </Grid>

       要想继续调整元素在单元格内的位置,可以通过上篇随笔中介绍的HorizontalAlignment、VerticalAlignment和Margin三个属性来实现,抄袭一张图片:

     

      调整之后示例代码的运行结果如下:

      

       

      在code中实现Grid 

         用xaml实现Grid布局虽然可以将行和列的定义与应用分开,但是代码十分冗长写起来真的是很痛苦,每一行和列都需要手动添加,尤其是行和列的定义部分显得很长。如果在实际开发中遇到相对复杂表单时,可以考虑在code中应用for循环来搞定。

      在code中可以通过GridLength类实现行和列的尺寸属性定义,三种定义的code实现方式如下:

    Auto

    GridLength.Auto

    Star

    new GridLength(1,GridUnitType.Star)

    Fixed

    new GridLength(100,GridUnitType.Pixel)

       给个简单的实例代码:

    1 Grid grid = new Grid();
    2  
    3 ColumnDefinition col1 = new ColumnDefinition();
    4 col1.Width = GridLength.Auto;
    5 ColumnDefinition col2 = new ColumnDefinition();
    6 col2.Width = new GridLength(1,GridUnitType.Star);
    7  
    8 grid.ColumnDefinitions.Add(col1);
    9 grid.ColumnDefinitions.Add(col2);

      以上就是关于Grid布局的简介。

      VariableSizedWrapGrid布局

      和上面介绍的Grid布局一样, VariableSizedWrapGrid 也是将布局容器按照行和列平均分割成若干单元格,并将所有的子元素排列其中。不同点在于VariableSizedWrapGrid的行和列数量是可变的。换一种理解方式,其本质就是最简单的布局方式——“流式布局”,只不过借用grid的展现方式而已。用流式布局的理解方式就很容易明白搞定VariableSizedWrapGrid布局的关键在于两点——确定子元素的“流动方向”(Orientation)和子元素“流动范围”(MaximumRowsOrColumns )。

      确定元素“流动方向”

      通过Orientation属性可以控制元素的排列方向。当赋值为Vertical时,元素按照竖直方向从左到右排列。此属性的默认值即为Vertical。

      给个例子:

     1 <VariableSizedWrapGrid Orientation="Vertical" Margin="20">
     2         
     3         <VariableSizedWrapGrid.Resources>
     4             <Style TargetType="Button">
     5                 <Setter Property="Background"
     6                            Value="LightBlue"/>
     7                 <Setter Property="Margin"
     8                         Value="20"/>
     9                 <Setter Property="Padding"
    10                         Value="10"/>
    11             </Style>
    12         </VariableSizedWrapGrid.Resources>
    13        
    14         <Button Content="Button1"/>
    15         <Button Content="Button2"/>
    16         <Button Content="Button3"/>
    17         <Button Content="Button4"/>
    18         <Button Content="Button5"/>
    19         <Button Content="Button6"/>
    20         <Button Content="Button7"/>
    21         <Button Content="Button8"/>
    22         <Button Content="Button9"/>
    23         <Button Content="Button0"/>
    24         
    25     </VariableSizedWrapGrid>

      效果图如下:

      若将Orientation属性改为Horizontal,则元素按照水平方向从左至右排列,效果:

      这个属性实在是很好理解,和其他“流式布局”相同,当窗口缩放时,元素的排列的行数和列数也会随之出现相应的变化。如果想要限定元素排列的行数或者列数就要用到MaximumRowsOrColumns属性了。

      确定元素“流动范围”

      通过对MaximumRowsOrColumns属性赋值可以限定元素的排列范围,但是这个属性的实际含义却取决于Orientation属性的值,借用上面的例子,当元素按竖直方向排列,并且为MaximumRowsOrColumns属性赋值“2”时:

    1     <VariableSizedWrapGrid Margin="20" Orientation="Vertical" MaximumRowsOrColumns="2">
    2         ......
    3         
    4     </VariableSizedWrapGrid>

    效果如下:

       结果所有Button整齐的排列成两行,并且位置固定,不随着窗口的缩放改变位置。可见当Orientation="Vertical"时,MaximumRowsOrColumns约束的是元素排列的最大“行数”。如果把元素的排列方向改为水平,其他不变:

    1     <VariableSizedWrapGrid Margin="20" Orientation="Horizontal" MaximumRowsOrColumns="2">
    2         ......
    3         
    4     </VariableSizedWrapGrid>

    则变为:

       则结果所有Button整齐的排列成两列,位置依然固定。由此可见当Orientation="Horizontal"时,MaximumRowsOrColumns约束的是元素排列的最大“列数”。

       虽然结果明了,但是过程比较费解。。为什么不把行和列分开约束呢??网上有关此布局的先关资料实在有限,本人也是通过实战方式得出结论,专业性肯定差点,如果查到相关资料我会第一时间修正。总之,有待继续学习。。好吧,暂时会用就行。。

      跨单元格排列元素

      以上例子中的元素都是按照单个单元格进行排,我们也可以使用VariableSizedWrapGrid.ColumnSpan和VariableSizedWrapGrid.RowSpan两个属性使元素跨单元格排列。举一个极简单的例子,将上面例子中的Button1和Button2修改如下:

    <Button VariableSizedWrapGrid.RowSpan="2" Content="Button1"/>
    <Button VariableSizedWrapGrid.ColumnSpan="2" Content="Button2"/>

    效果如下:

      这两个布局的基本用法先介绍到这里。。一篇随笔介绍两个布局貌似篇幅有点大。。下篇随笔准备介绍两种简单的布局——StackPanel和RelativePanel。

  • 相关阅读:
    NOIP201105铺地毯
    50148155HYF旅游
    连通性判断
    传递消息1
    找朋友
    5796: 最短Hamilton路径(状压dp)
    2283: A Mini Locomotive(01背包)
    2616: Cow Frisbee Team(01背包)
    2593: Secret Message(字典树)
    Stammering Aliens(二分+Hash 卡过)
  • 原文地址:https://www.cnblogs.com/shiliangvv/p/5099634.html
Copyright © 2020-2023  润新知