Grid之 Gridlength 解析

常见的Grid 布局代码如下:

  <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="Auto"/>

                <!--(600-30-350)*(80/(80+20))=176-->

                <ColumnDefinition Width="80*"/>

                <ColumnDefinition Width="20*"/>

                <ColumnDefinition Width="30"/>

            </Grid.ColumnDefinitions>

            <TextBlock Background="Aqua"  Text="Auto"  Width="350"  Grid.Column="0" />

            <TextBlock Background="RosyBrown" Text="80*"  Grid.Column="1" />

            <TextBlock Background="Bisque" Text="20*"  Grid.Column="2"/>

            <TextBlock Background="Bisque" Text="30"  Grid.Column="3"/>

        </Grid>

ColumnDefinition  的属性Width值有三种类型,

Msdn 解释如下:

Auto

The size is determined by the size properties of the content object.  

Pixel

The value is expressed as a pixel.  

Star

The value is expressed as a weighted proportion of available space.  

Auto:根据子控件的要求,给予需要的控件

Pixel:固定值

Star:按照加权比例分配。

如果三者混合使用,该如何分配呢,看下图

 

分析源代码

第一行:

<!--If you set ColumnDefinition Width is pixel value,this column's width will be a fixed value,maybe there is free space-->

        <Grid Height="30"   VerticalAlignment="Top" ShowGridLines="True">

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="50"/>

                <ColumnDefinition Width="50"/>

                <ColumnDefinition Width="50"/>

            </Grid.ColumnDefinitions>

            <TextBlock Background="Aqua"  Text="50"  Grid.Column="0"/>

            <TextBlock Background="RosyBrown" Text="50"  Grid.Column="1"/>

            <TextBlock Background="Bisque" Text="50"  Grid.Column="2"/>

        </Grid>

每一列都是固定数值,剩余空间留空。

第二行:

<Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="True">

            <Grid.ColumnDefinitions>

                <!--600*(40/(40+40+20))=240-->

                <ColumnDefinition Width="40*"/>

                <ColumnDefinition Width="20*"/>

                <ColumnDefinition Width="40*"/>

            </Grid.ColumnDefinitions>

            <TextBlock Background="Aqua" Text="40*"   TextAlignment="Center" Grid.Column="0"/>

            <TextBlock Background="RosyBrown" Text="20*"   Grid.Column="1"/>

            <TextBlock Background="Bisque" Text="40*"  Grid.Column="2"/>

</Grid>

 

每一列都是加权数值,按照比例分配,

例如,Grid总宽度为600,第一列宽度值为40* ,实际数值为 600*(40/(40+40+20))=240 。

第三行:

  <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >

            <Grid.ColumnDefinitions>

                <!--(600-100)*(40/(40+60))=200-->

                <ColumnDefinition Width="40*"/>

                <ColumnDefinition Width="60*"/>

                <ColumnDefinition Width="100"/>

            </Grid.ColumnDefinitions>

            <TextBlock Background="Aqua"  Text="40*"   Grid.Column="0" />

            <TextBlock Background="RosyBrown"  Text="60*"  Grid.Column="1" />

            <TextBlock Background="Bisque"  Text="100"  Grid.Column="2"/>

        </Grid>

这一列既有固定数字,也有加权比例,该如何计算呢?

以第一列为例,总宽度依然为600

先减去固定的数值100,剩下的部分 由两个加权比例列(40*/60*)瓜分,如下:

600-100)*(40/(40+60))=200

第四行:

        <!--If the  ColumnDefinition width  is  star ,and others is not, the start mean "1*",calculate as above -->

        <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >

            <Grid.ColumnDefinitions>

                <!--(600-30)*(1/(1+30))=18.3-->

                <ColumnDefinition Width="*"/>

                <ColumnDefinition Width="30*"/>

                <ColumnDefinition Width="30"/>

            </Grid.ColumnDefinitions>

            <TextBlock Background="Aqua"  Text="*"  Grid.Column="0" />

            <TextBlock Background="RosyBrown"  Text="30*" Grid.Column="1" />

            <TextBlock Background="Bisque"  Text="30" Grid.Column="2"/>

        </Grid>

注意,第一列宽度为* ,第二列为30* ,这个该如何处理呢?当有两个加权分配时,其中的* 实际含义为1*,所以第一列宽度为

(600-30)*(1/(1+30))=18.3

第五行:

<Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="Auto"/>

                <!--(600-30-350)*(80/(80+20))=176-->

                <ColumnDefinition Width="80*"/>

                <ColumnDefinition Width="20*"/>

                <ColumnDefinition Width="30"/>

            </Grid.ColumnDefinitions>

            <TextBlock Background="Aqua"  Text="Auto"  Width="350"  Grid.Column="0" />

            <TextBlock Background="RosyBrown" Text="80*"  Grid.Column="1" />

            <TextBlock Background="Bisque" Text="20*"  Grid.Column="2"/>

            <TextBlock Background="Bisque" Text="30"  Grid.Column="3"/>

        </Grid>

最复杂的就是这一列,各种东东都混合进来了,一个一个来吧。

第一列,Auto,看这一列的控件,锁定了宽度350,那么第一列就固定了350

第二、三列为加权比例,先放放

第四列固定宽度,不用考虑了。

那么第二列宽度为

(600-30-350)*(80/(80+20))=176

 

第六行

  <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="Auto"/>

                <!--(600-30-380)=190-->

                <ColumnDefinition Width="*"/>

                <ColumnDefinition Width="30"/>

            </Grid.ColumnDefinitions>

            <TextBlock Background="Aqua"  Text="Auto"  Width="380"  Grid.Column="0" />

            <TextBlock Background="RosyBrown" Text="*"  Grid.Column="1" />

            <TextBlock Background="Bisque" Text="30"  Grid.Column="2"/>

        </Grid>

三种值类型同时出现,加权列的优先级最低,固定列的优先级最高。

第二列的计算方式为

(600-30-380)=190

 

另外,用cs代码定义GridLength 这样写:

GridLength fixedLength = new GridLength(20);

GridLength starLength = new GridLength(20, GridUnitType.Star);

GridLength autoLength = GridLength.Auto;

 

 

上例中XAML 完整代码如下

    <StackPanel   Width="600">
        <StackPanel.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="TextAlignment" Value="Center" />
            </Style>
        </StackPanel.Resources>
        <!--If you set ColumnDefinition Width is pixel value,this column's width will be a fixed value,maybe there is free space-->
        <Grid Height="30"   VerticalAlignment="Top" ShowGridLines="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50"/>
                <ColumnDefinition Width="50"/>
                <ColumnDefinition Width="50"/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Aqua"  Text="50"  Grid.Column="0"/>
            <TextBlock Background="RosyBrown" Text="50"  Grid.Column="1"/>
            <TextBlock Background="Bisque" Text="50"  Grid.Column="2"/>
        </Grid>

        <!--If the  ColumnDefinition width  is  all star value,this column's width will be  the whole value multiplication it's rate -->
        <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="True">
            <Grid.ColumnDefinitions>
                <!--600*(40/(40+40+20))=240-->
                <ColumnDefinition Width="40*"/>
                <ColumnDefinition Width="20*"/>
                <ColumnDefinition Width="40*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Aqua" Text="40*"   TextAlignment="Center" Grid.Column="0"/>
            <TextBlock Background="RosyBrown" Text="20*"   Grid.Column="1"/>
            <TextBlock Background="Bisque" Text="40*"  Grid.Column="2"/>
        </Grid>
        <TextBlock HorizontalAlignment="Left" Text="600*(40/(40+40+20))=240" Width="240" Height="30" Margin="0,0,0,0" Background="YellowGreen" />

        <!--If the  ColumnDefinition width  is  star value,and others is not,  the whole value subtrace fixed value that which column's width is fixed value
       then   multiplication it's rate -->
        <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >
            <Grid.ColumnDefinitions>
                <!--(600-100)*(40/(40+60))=200-->
                <ColumnDefinition Width="40*"/>
                <ColumnDefinition Width="60*"/>
                <ColumnDefinition Width="100"/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Aqua"  Text="40*"   Grid.Column="0" />
            <TextBlock Background="RosyBrown"  Text="60*"  Grid.Column="1" />
            <TextBlock Background="Bisque"  Text="100"  Grid.Column="2"/>
        </Grid>
        <TextBlock HorizontalAlignment="Left" Width="200" Text="(600-100)*(40/(40+60))=200" Height="30" Margin="0,0,0,0" Background="YellowGreen" />

        <!--If the  ColumnDefinition width  is  star ,and others is not, the start mean "1*",calculate as above -->
        <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >
            <Grid.ColumnDefinitions>
                <!--(600-30)*(1/(1+30))=18.3-->
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="30*"/>
                <ColumnDefinition Width="30"/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Aqua"  Text="*"  Grid.Column="0" />
            <TextBlock Background="RosyBrown"  Text="30*" Grid.Column="1" />
            <TextBlock Background="Bisque"  Text="30" Grid.Column="2"/>
        </Grid>
        <TextBlock HorizontalAlignment="Left" Width="18.3" Height="30" Margin="0,0,0,0" Background="YellowGreen" 
                   Text="18.3" ToolTip="(600-30)*(1/(30+1))=18.3" />

        <!--If the  ColumnDefinition width  is  Auto ,it's width will be determined by content width,the content object has highest priority.if it want,it can use all space  of parent -->
        <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <!--(600-30-350)*(80/(80+20))=176-->
                <ColumnDefinition Width="80*"/>
                <ColumnDefinition Width="20*"/>
                <ColumnDefinition Width="30"/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Aqua"  Text="Auto"  Width="350"  Grid.Column="0" />
            <TextBlock Background="RosyBrown" Text="80*"  Grid.Column="1" />
            <TextBlock Background="Bisque" Text="20*"  Grid.Column="2"/>
            <TextBlock Background="Bisque" Text="30"  Grid.Column="3"/>
        </Grid>
        <TextBlock HorizontalAlignment="Left" Text="(600-30-350)*(80/(80+20))=176" Width="176" Height="30" Margin="350,0,0,0" Background="YellowGreen" />

 
        <Grid Height="30"  Margin="0,20,0,0"  VerticalAlignment="Top" ShowGridLines="False" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <!--(600-30-380)=190-->
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="30"/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Aqua"  Text="Auto"  Width="380"  Grid.Column="0" />
            <TextBlock Background="RosyBrown" Text="*"  Grid.Column="1" />
            <TextBlock Background="Bisque" Text="30"  Grid.Column="2"/>
        </Grid>
        <TextBlock Background="YellowGreen" HorizontalAlignment="Left" Margin="380,0,0,0" Height="30" Text="(600-30-380)=190" Width="190" />
    </StackPanel>

 

 

posted @ 2011-04-29 10:04  xiaokang088  阅读(3910)  评论(1编辑  收藏  举报