五. Grid
Grid顾名思义就是“网格”,它的子控件被放在一个一个实现定义好的小格子里面,整齐配列。 Grid和其他各个Panel比较起来,功能最多也最为复杂。要使用Grid,首先要向RowDefinitions和ColumnDefinitions属性中添加一定数量的RowDefinitions和 ColumnDefinitions元素,从而定义行数和列数。而放置在Grid面板中的控件元素都必须显示采用附加属性语法定义其 放置所在的行和列,它们都是以0为基准的整型值,如果没有显式设置任何行或列,Grid将会隐式地将控件加入在第0行第0列。由于Grid的组成并非简单的添加属性标记来区分行列,这也使得用户在实际应用中可以具体到某一单元格中,所以布局起来就很精细了。
Grid的单元格可以是空的,一个单元格中可以有多个元素,而在单元格中元素是根据它们的Z顺序一个接着一个呈现的。与Canvas一样,同一个单元格中的子元素不会与其他元素交互布局,信息——它们仅仅是重叠而已。接下来我们来使用一些实际的代码演示一下如何使用GRID。
1) Grid的列宽与行高可采用固定、自动、按比列三种方式定义
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="300"></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
注意:这里介绍一下Grid高度、宽度的几种定义方式:
名称 | 说明 |
---|---|
绝对尺寸 | 就是给一个实际的数字,但通常将此值指定为整数,像上图中中那样 |
自动(Autosizing) | 值为Auto,实际作用就是取实际控件所需的最小值 |
StarSizing | 值为* 或N* ,实际作用就是取尽可能大的值,当某一列或行被定义为* 则是尽可能大,当出现多列或行被定义为*则是代表几者之间按比例设置尺寸 |
第一种,固定长度——宽度不够,会裁剪,不好用。单位pixel。 第二种,自动长度——自动匹配列中最长元素的宽度。 第三种,比例长度——* 表示占用剩余的全部宽度;两行都是* ,将平分剩余宽度;像上面的一个2* ,一个*,表示前者2/3宽度。
2) 跨越多行和多列
<Rectangle Width="250" Height="40" Fill="Red" Grid.Column="1" Grid.ColumnSpan="3"/>
使用 Grid.ColumnSpan 和 Grid.RowSpan 附加属性可以让相互间隔的行列合并,所以元素也可以跨越多个单元格。
3) 使用 GridSplit 分割
<GridSplitter Height="6" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Grid.Row="2" Grid.Column="2"></GridSplitter>
<Window x:Class="项目6.MainWindow"
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"
xmlns:local="clr-namespace:项目6"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="750">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="61*"></RowDefinition>
<RowDefinition Height="101*"></RowDefinition>
<RowDefinition Height="108*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="139"></ColumnDefinition>
<ColumnDefinition Width="184"></ColumnDefinition>
<ColumnDefinition Width="45*"></ColumnDefinition>
<ColumnDefinition Width="250"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Background="Red" Text="第一行,第一列,占一列" VerticalAlignment="Center"></TextBox>
<Button Margin="15" Grid.Column="1" Grid.ColumnSpan="3" Grid.RowSpan="2" Content="从第一行第二列开始,占两行,三列" />
<Button Margin="25" Grid.Row="1" Name="Button">后台生成代码</Button>
<Button Margin="30" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4" Content="第三行,第一列开始,占4列"></Button>
</Grid>
</Window>
5) 下图,以 C# 代码实现:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace 项目6 {
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window {
public MainWindow()
{
InitializeComponent();
}
private void Button_Ok_Click(object sender, RoutedEventArgs e)
{
var grid=new Grid();
grid.Width=Double.NaN;//相当于在XAML中设置Width="Auto"
grid.Height=Double.NaN;
Content = grid;
var cd1=new ColumnDefinition();
cd1.Width=new GridLength(139);
grid.ColumnDefinitions.Add(cd1);
var cd2=new ColumnDefinition();
cd2.Width=new GridLength(1,GridUnitType.Star);
grid.ColumnDefinitions.Add(cd2);
var cd3=new ColumnDefinition();
cd3.Width=new GridLength(2,GridUnitType.Star);
grid.ColumnDefinitions.Add(cd3);
var rd1=new RowDefinition();
rd1.Height=new GridLength(61);
grid.RowDefinitions.Add(rd1);
var rd2=new RowDefinition();
rd1.Height=new GridLength(1,GridUnitType.Star);
grid.RowDefinitions.Add(rd2);
var rd3=new RowDefinition();
rd1.Height=new GridLength(200);
grid.RowDefinitions.Add(rd3);
var rec1=new Rectangle();
rec1.Fill=new SolidColorBrush(Colors.Gray);
rec1.SetValue(Grid.ColumnProperty,0);
rec1.SetValue(Grid.RowProperty,0);
grid.Children.Add(rec1);
var rec2=new Rectangle();
rec2.Fill=new SolidColorBrush(Colors.Yellow);
rec2.SetValue(Grid.ColumnProperty,1);
rec2.SetValue(Grid.ColumnSpanProperty,2);
rec2.SetValue(Grid.RowProperty,1);
rec2.SetValue(Grid.RowSpanProperty,2);
grid.Children.Add(rec2);
}
}
}
六、 UniformGrid
介绍了前面的 Grid, 接下来介绍的这个 UniformGrid 就是 Grid 的简化版,每个单元格的大小相同,不需要定义行列集合。每个单元格始终具有相同的大小,每个单元格只能容纳一个控件,将自动按照定义在其内部的元素个数,自动创建行列,并通常保持相同的行列数。UniformGrid 中没有 Row 和 Column 附加属性,也没有空白单元格。
与 Grid 布局控件相比,UniformGrid 布局控件很少使用。Grid 面板是用于创建简单乃至复杂窗口布局的通用工具。UniformGrid 面板是一个一种更特殊的布局容器,主要用于在一个刻板的网格中快速地布局元素。
下面用 XAML 代码实现一个示例,该示例使用 4 个按钮填充 UniformGrid 面板。:
<Grid>
<UniformGrid Rows="2" Columns="2">
<Button Margin="50">第一个(0,0)</Button>
<Button Margin="50">第二个(0,1)</Button>
<Button Margin="50">第三个(1,0)</Button>
<Button Margin="50" Name="ButtonAddByCode">第四个(1,1)</Button>
</UniformGrid>
</Grid>
下面使用 C# 代码实现 15 个 TextBlock 的控件的布局。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Shapes;
namespace 项目6 {
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window {
public MainWindow()
{
InitializeComponent();
}
private void ButtonAddByCode_Click(object sender, RoutedEventArgs e)
{
var ug = new UniformGrid();
Content = ug;
ug.Margin=new Thickness(15);
ug.Background=new SolidColorBrush(Colors.Yellow);
TextBlock block;
for (int i = 0; i < 15; i++)
{
block=new TextBlock();
block.Background=new SolidColorBrush(Colors.AliceBlue);
block.VerticalAlignment = VerticalAlignment.Center;
block.HorizontalAlignment = HorizontalAlignment.Center;
block.Margin=new Thickness(25,25,25,25);
block.Text = "C# 第" + i.ToString("00")+ "个";
ug.Children.Add(block);
}
}
}
}