WPF教程六:布局之Grid面板(转)
WPF教程六:布局之Grid面板
Grid:网格面板
Grid顾名思义就是“网格”,以表格形式布局元素,对于整个面板上的元素进行布局,它的子控件被放在一个一个事先定义好的小格子里面,整齐配列。 Grid和其他各个Panel比较起来,功能最多也最为复杂。要使用Grid,首先要向RowDefinitions和ColumnDefinitions属性中添加一定数量的RowDefinitions和 ColumnDefinitions元素,从而定义行数和列数。而放置在Grid面板中的控件元素都必须显示采用Row和Column附加属性定义其放置所在的行和列,这两个属性的值都是从0开始的索引数,如果没有显式设置任何行或列,Grid将会隐式地将控件加入在第0行第0列。由于Grid的组成并非简单的添加属性标记来区分行列,这也使得用户在实际应用中可以具体到某一单 元格中,所以布局起来就很精细了。 列宽和行高,分别可以在ColumnDefinition、RowDefinition里面指定Width、Height的值。
Grid的单元格可以是空的,一个单元格中可以有多个元素,而在单元格中元素是根据它们的Z顺序一个接着一个呈现的。与Canvas一样,同一个单元格中 的子元素不会与其他元素交互布局,信息——它们仅仅是重叠而已。
Grid面板将元素分割到不可见的行列网格中。尽管可以在一个单元格中放置多个元素(这时这些元素会相互重叠),但在每个单元格中只放置一个元素通常更合理。当然,在Grid单元格中的元素本身也可能是另一个容器,该容器组织它所包含的一组控件。
注意:尽管Grid面板被设计成不可见的,但可将Grid.ShowGridLines属性设置为True,从而更清晰的观察Grid面板,方便调试,可以更准确地控制Grid面板如何选择列宽和行高。
1、定义一个两行三列的Grid,在每个单元格里面放置一个Button按钮
使用XAML代码实现:
1 <Window x:Class="WpfDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="Grid面板" Height="237" Width="525" WindowStartupLocation="CenterScreen"> 5 <!--定义网格,此处显示了网格线--> 6 <Grid ShowGridLines="True"> 7 <Grid.RowDefinitions> 8 <RowDefinition></RowDefinition> 9 <RowDefinition></RowDefinition> 10 </Grid.RowDefinitions> 11 <Grid.ColumnDefinitions> 12 <ColumnDefinition></ColumnDefinition> 13 <ColumnDefinition></ColumnDefinition> 14 <ColumnDefinition></ColumnDefinition> 15 </Grid.ColumnDefinitions> 16 <Button Grid.Row="0" Grid.Column="0">Top Left</Button> 17 <Button Grid.Row="0" Grid.Column="1">Middle Left</Button> 18 <Button Grid.Row="1" Grid.Column="2">Button Right</Button> 19 <Button Grid.Row="1" Grid.Column="1">Button Middle</Button> 20 </Grid> 21 </Window>
注意:如果不知道Grid.Row属性,Grid面板会假定该属性的值为0。对于Grid.Column属性也是如此。因此,在Grid面板的第一个单元格中放置元素时可不指定这两个属性值。
2、 调整行高和列宽
如果Grid面板只是按比例分配尺寸的行和列的集合,它也就没有什么用处了。为了充分发挥Grid面板的潜能,可更改每一行和每一列的尺寸设置方式。
Grid面板支持以下三种设置尺寸的方式:
名称 |
说明 |
绝对设置尺寸方式 |
使用设备无关单位准确地设置尺寸,就是给一个实际的数字,但通常将此值指定为整数。这是最无用 的策略,因为这种策略不够灵活,难以适应内容大小和容器大小的改变,而且难以处理本地化。 |
自动设置尺寸方式 |
值为Auto,实际作用就是取实际控件所需的最小值,每行和每列的尺寸刚好满足需要,这是最有用 的尺寸设置方式。 |
按比例设置尺寸方式 |
按比例将空间分割到一组行和列中。这是对所有行和列的标准设置。通常值为*或N*,实际作用就是取尽可能大的值,当某一列或行被定义为*则是尽可能大,当出现多列或行被定义为*则是代表几者之间按比例方设置尺寸。 |
为了获得最大的灵活性,可混合使用这三种尺寸设置方式。例如,创建几个自动设置尺寸的行,然后通过按比例设置尺寸的方式让最后的一行或两行充满剩余的空间,这通常是很有用的。
可通过设置ColumnDefinition对象的Width属性或者RowDefinition对象的Height属性来确定尺寸设置方式。
(1)设置100设备无关单位的绝对宽度:
<ColumnDefinition Width="100"></ColumnDefinition>
(2)使用自动尺寸设置方式,需要使用Auto值
<ColumnDefinition Width="Auto"></ColumnDefinition>
(3)使用按比例尺寸设置方式,需要使用星号(*)
<ColumnDefinition Width="*"></ColumnDefinition>
如果希望不均匀的分割剩余空间,可指定权重,权重必须放在星号之前。例如,如果有两行是按比例设置尺寸,并希望第一行的高度是第二行高度的一半,那么可以使用如下设置来分配剩余空间:
<RowDefinition Height="*"></RowDefinition> <RowDefinition Height="2*"></RowDefinition>
使用XAML代码定义一个3行4列的Grid
<Window x:Class="WpfDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Grid面板" Height="237" Width="525" WindowStartupLocation="CenterScreen">
<!--定义网格,此处显示了网格线-->
<Grid ShowGridLines="True">
<!--定义行,3行-->
<Grid.RowDefinitions>
<!--自动行高-->
<RowDefinition Height="Auto"></RowDefinition>
<!--按比例行高-->
<RowDefinition Height="*"></RowDefinition>
<!--固定行高-->
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<!--定义列,2列-->
<Grid.ColumnDefinitions>
<!--按比例列宽-->
<ColumnDefinition Width="*"></ColumnDefinition>
<!--固定列宽-->
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!--定义元素,并指定单元格-->
<TextBlock Grid.Row="0" Grid.Column="0" >第一行第一列</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0" >第二行第一列</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="0" >第三行第一列</TextBlock>
<Button Grid.Row="0" Grid.Column="1">第一行第二列</Button>
<Button Grid.Row="1" Grid.Column="1">第二行第二列</Button>
<Button Grid.Row="2" Grid.Column="1">第三行第二列</Button>
</Grid>
</Window>
运行效果图:
3、跨越多行和多列
除了可以使用Row和Column附加属性在单元格中放置元素,还可以使用另外两个附加属性使元素跨越多个单元格,这两个附加属性是RowSpan和ColumnSpan。
例如,下面的按钮将占据第一行中的第一个和第二个单元格的所有空间:
<Button Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">Span Button</Button>
下面的代码通过跨越两行和两列,拉伸按钮使其占据所有4个单元格:
<Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2">Span Button</Button>
示例
1 <Window x:Class="WpfDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="Grid面板" Height="237" Width="525" WindowStartupLocation="CenterScreen"> 5 <!--定义网格,此处显示了网格线--> 6 <Grid ShowGridLines="True"> 7 <Grid.RowDefinitions> 8 <RowDefinition Height="*"></RowDefinition> 9 <RowDefinition Height="Auto"></RowDefinition> 10 </Grid.RowDefinitions> 11 <Grid.ColumnDefinitions> 12 <ColumnDefinition Width="*"></ColumnDefinition> 13 <ColumnDefinition Width="Auto"></ColumnDefinition> 14 <ColumnDefinition Width="Auto"></ColumnDefinition> 15 </Grid.ColumnDefinitions> 16 <TextBox Margin="10" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">thie is a test</TextBox> 17 <Button Margin="10,10,2,10" Padding="3" Grid.Row="1" Grid.Column="1">OK</Button> 18 <Button Margin="10,10,2,10" Padding="3" Grid.Row="1" Grid.Column="2">Cancle</Button> 19 </Grid> 20 </Window>
界面运行效果:
4、分割窗口
每个Windows用户都见过分隔条—能将窗口的一部分与另一部分分类的可拖动分割器。例如,当使用Windows资源管理器时,会看到一系列文件夹(在左边)和一系列文件(在右边)。可拖动它们之间的分隔条来确定每部分占据窗口的比例。
在WPF中,分隔条由GridSplitter类表示,它是Grid面板的功能之一。通过为Grid面板添加GridSplitter对象,用户就可以改变行和列的尺寸。例如:
1 <Window x:Class="WpfDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="Grid面板" Height="237" Width="525" WindowStartupLocation="CenterScreen"> 5 <!--定义网格,此处显示了网格线--> 6 <Grid ShowGridLines="True"> 7 <Grid.RowDefinitions> 8 <RowDefinition ></RowDefinition> 9 <RowDefinition ></RowDefinition> 10 </Grid.RowDefinitions> 11 <Grid.ColumnDefinitions> 12 <ColumnDefinition Width="100"></ColumnDefinition> 13 <ColumnDefinition Width="Auto"></ColumnDefinition> 14 <ColumnDefinition Width="50"></ColumnDefinition> 15 </Grid.ColumnDefinitions> 16 <Button Grid.Row="0" Grid.Column="0" Margin="3">Left</Button> 17 <Button Grid.Row="0" Grid.Column="2" Margin="3">Right</Button> 18 <Button Grid.Row="1" Grid.Column="0" Margin="3">Left</Button> 19 <Button Grid.Row="1" Grid.Column="2" Margin="3">Right</Button> 20 21 <GridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Width="3" VerticalAlignment="Stretch" 22 HorizontalAlignment="Center" ShowsPreview="False"></GridSplitter> 23 </Grid> 24 </Window>
界面运行效果:
可以通过拖动中间的分割条,来改变两列的相对宽度,效果如下图所示:
注意:为了成功地创建GridSplitter对象,务必为VerticalAlignment(垂直对齐方式)、HorizontalAlignment(水平对齐方式)以及width属性(或Height属性)提供相应的属性值。
理解如何使用GridSplitter类,从而得到所期望的效果需要一定的经验,下面列出几条指导原则:
(1)GridSplitter对象必须放在Grid单元格中,可与以及存在的内容一并放到单元格中,这时需要调整边距设置,使他们不相互重叠。更好的方法是预留一列或一行专门用于放置GridSplitter对象,并将预留行或列的Height或Width属性的值设置为Auto。
(2)GridSplitter对象总是改变整行或整列的尺寸(而非改变单个单元格的尺寸)。为使GridSplitter对象的外观和行为保持一致,需要拉伸GridSplitter对象使其穿越整行或整列,而不是将其限制在单元格中。为此,可使用RowSpan或ColumnSpan属性。例如,上面的例子中GridSplitter对象的RowSpan属性设置为2,因此被拉伸充满整列。如果不使用该设置,GridSplitter对象会显示在顶行(放置它的行)中,即使这样,拖动分隔条时也会改变整列的尺寸。
(3)GridSplitter对象很小不易看见,为了使其更可用,需要为其设置最小尺寸。在上面的例子中,对于垂直分隔条,需要将VerticalAlignment属性设置为Stretch(使分隔条填满区域的整个高度),并将Width设置为固定值。对于水平分隔条,需要设置HorizontalAlignment属性来拉伸,并将Height属性设置为固定值。
(4)GridSplitter对齐方式还决定了分隔条是水平的(用于改变行的尺寸)还是竖直的(用于改变列的尺寸)。对于水平分隔条,需要将VerticalAlignment属性设置为Center(这也是默认值),以指明拖动分隔条改变上面行和下面行的尺寸。对于垂直分隔条,需要将HorizontalAlignment属性设置为Center,以改变分隔条两侧列的尺寸。
在上面的例子中还包含了一处额外的细节。在声明GridSplitter对象时,将ShowPreview属性设置为false,因此,当把分隔条从一边拖到另一边时,会立即改变列的尺寸。但是如果将ShowPreview属性设置为true,当拖到分隔条时就会看到一个灰色的阴影跟随鼠标指针,用于显示将在何处进行分割。并且直到释放了鼠标键之后列的尺寸才改变。如果GridSplitter对象获得了焦点,也可以使用箭头键改变相应的尺寸。
提示:可以改变GridSplitter对象的填充方式,使其不只是具有阴影的灰色矩形。技巧是使用Background属性应用填充,该属性可以接收简单的颜色或更复杂的画刷。