用Grid和GridSplitter布局和分割WPF窗口

扣扣技术交流群:460189483

我将通过一个实例一步步添加分割栏来尽量覆盖不同的分割风格。 首先你要创建一个新的工程:启动Visual Studio 2017,在开始页面点击Create-> Project来创建一个WPF Application,姑且将此应用程序命名为WindowGridSplit。创建完成后直接运行,出现下面的界面,这就是我们要展示Power的地方

图1 GridSplitter施展才能的地方

1. 将其分格为两列
    将主窗口分割为两列(或者两行),差不多是最常见的分割方法。
    打开Window1.xaml文件,为主窗口的Grid添加一个名字为gridMain,以便后面与其他Grid做区分。通过gridMain,我们将主窗口分解为3:7的两列,分别在其中添加标签并将其背景以不同颜色填充以便显示其拖动的效果;在gridMain中添加GridSplitter控件,我们可以看到,在没有指定任何属性的情况下,GridSplitter是一个在Column1里面且自动停靠在Column1的右侧的分割栏。认识到这一点非常重要,因为我们要控制它的停靠行为,只有通过修改相关“默认属性”才能达到目的。由于没有指定任何Grid.Row和Grid.Column属性,所以默认都是Grid.Row=“0”、Grid.Column=“0”,同样,HorizontalAlignment="Right" VerticalAlignment="Stretch":

<Window x:Class="WindowGridSplit.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid Name="gridMain">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30*"/>
            <ColumnDefinition Width="70*"/>
        </Grid.ColumnDefinitions>
        <Label Background="LightBlue" VerticalContentAlignment="Center"                 
               HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="0">Column1</Label>
        <GridSplitter Width="5"></GridSplitter>
        <Label Background="LightGreen" VerticalContentAlignment="Center" 
               HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="1">Column2</Label>
    </Grid>
</Window>

图2 分割成两列

小技巧:
由于WPF对控件的布局是解释执行的,所以你的控件出现的先后将直接影响到他们彼此的覆盖关系,就像上面的那样:

<Label Background="LightBlue" VerticalContentAlignment="Center" 
       HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="0">Column1</Label> <GridSplitter Width="5"></GridSplitter>

由于GridSplitter默认Grid.Row=“0”、Grid.Column=“0”,那么它将与Label占用同一列,GridSplitter宽为5像素,它将覆盖Label 5像素。
但是如果以上两行位置掉转,则会出现严重的问题:GridSplitter不可见:
 

<GridSplitter Width="5"></GridSplitter>
<Label Background="LightBlue" VerticalContentAlignment="Center" 
       HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="0">Column1</Label>

2. 将Column2分割为两行
    有人可能希望将主窗口分割为左列放置TreeView,用语导航,右面分为上下两行,用于显示导航界面和信息,这是更加常见的一种需求。那么只要把上面的Column2再分解为两行,就可以达到目的了:

<Window x:Class="WindowGridSplit.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid Name="gridMain">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30*"/>
            <ColumnDefinition Width="70*"/>
        </Grid.ColumnDefinitions>
        <Label Background="LightBlue" VerticalContentAlignment="Center" 
               HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="0">Column1</Label>
        <GridSplitter Width="5"></GridSplitter>
        <Label Background="LightGreen" VerticalContentAlignment="Center" 
               HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="1">Column2</Label>
        <Grid Name="gridRightColumn" Grid.Row="0" Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <GridSplitter Width="5"></GridSplitter>
        </Grid>
    </Grid>
</Window>

上面的代码中我同样添加了一个具有默认属性的GridSplitter,试图将Column2分解为两行,问题出现了:

GridSplitter被默认分配到了第一行的右侧。还好,上面打了预防针,该知道怎么修改它了:
 

<GridSplitter Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"></GridSplitter>

然后添加一些标签并分配不同颜色用于区分:
 

<Window x:Class="WindowGridSplit.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid Name="gridMain">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30*"/>
            <ColumnDefinition Width="70*"/>
        </Grid.ColumnDefinitions>
        <Label Background="LightBlue" VerticalContentAlignment="Center" 
              HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="0">Column1</Label>
        <GridSplitter Width="5"></GridSplitter>
        <Label Background="LightGreen" VerticalContentAlignment="Center" 
              HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="1">Column2</Label>
        <Grid Name="gridRightColumn" Grid.Row="0" Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Label Grid.Row="0" Grid.Column="0" Width="60" Height="60" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="HotPink">Row1</Label>
            <GridSplitter Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"></GridSplitter>
            <Label Grid.Row="1" Grid.Column="0" Width="60" Height="60" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="HotPink">Row2</Label>
        </Grid>
    </Grid>
</Window>

运行结果如下:

图4 水平分割

3. 交叉分割
    其实大部分应用到上面就足够了。下面介绍一下交叉分割,其实也非常简单,就是RowSpan和ColumnSpan的设置问题。
    继续上面的程序,将Row1分解为四个平分窗口:

<Window x:Class="WindowGridSplit.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid Name="gridMain">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30*"/>
            <ColumnDefinition Width="70*"/>
        </Grid.ColumnDefinitions>
        <Label Background="LightBlue" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="0">Column1</Label>
        <GridSplitter Width="5"></GridSplitter>
        <Label Background="LightGreen" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="1">Column2</Label>
        <Grid Name="gridRightColumn" Grid.Row="0" Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Label Grid.Row="0" Grid.Column="0" Width="60" Height="60" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="HotPink">Row1</Label>
            <Grid Grid.Row="0" Grid.Column="0" >
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center">Cell11</TextBlock>
                <TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">Cell12</TextBlock>
                <TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center">Cell21</TextBlock>
                <TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">Cell22</TextBlock>
                <GridSplitter Width="5" Grid.RowSpan="2"></GridSplitter>
                <GridSplitter Height="5" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"></GridSplitter>
            </Grid>
            <GridSplitter Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"></GridSplitter>
            <Label Grid.Row="1" Grid.Column="0" Width="60" Height="60" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="HotPink">Row2</Label>
        </Grid>
    </Grid>
</Window>

图5 交叉分割

运行结果:

图5 交叉分割

4. GridSplitter独霸一行
    以上介绍的分割栏GridSplitter都是与Grid的其它的GridRow、GridColumn在同一行或者列的,当然你也可以把GridSplitter单独放在一行/列中,设置方式与共享栏方式一样,这里就不错过多描述了。
 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值