Grid之Margin+Alignment解析

Grid 布局时经常用到Margin和Alignment,两者互相配合,进行布局,例如:

     <TextBlock HorizontalAlignment="Right"  VerticalAlignment="Center" Margin="0,0,100,0" Width="100" Height="50" Background="Yellow"  >Right+Center+0,0,100,0</TextBlock>

 

先上概念: 

Margin   <200,100,0,0>        对应<Left,Top,Right,Bottom> <左,上,右,下>

从左开始顺时针转

    public enum HorizontalAlignment

    {

        // 摘要:

        //     与父元素布局槽的左侧对齐的元素。

        Left = 0,

        //

        // 摘要:

        //     与父元素布局槽的中心对齐的元素。

        Center = 1,

        //

        // 摘要:

        //     与父元素布局槽的右侧对齐的元素。

        Right = 2,

        //

        // 摘要:

        //     拉伸以填充整个父元素布局槽的元素。

        Stretch = 3,

    }

在元素上显式设置 HeightWidth 属性时,这些度量值在布局过程中将具有较高的优先级,并且取消将 HorizontalAlignment 设置为 Stretch 的典型效果。

    public enum VerticalAlignment

    {

        // 摘要:

        //     子元素与父级布局槽的顶端对齐。

        Top = 0,

        //

        // 摘要:

        //     子元素与父级布局槽的中心对齐。

        Center = 1,

        //

        // 摘要:

        //     子元素与父级布局槽的底端对齐。

        Bottom = 2,

        //

        // 摘要:

        //     子元素拉伸至填满父级布局槽。

        Stretch = 3,

    }

下面解析一下两者之间的关系。

 

第一类:停靠四周 ,例如

         <TextBlock Background="Yellow" Margin="200,100,0,0"     HorizontalAlignment="Left" VerticalAlignment="Top" Text="Left+Top+200,100,0,0" />

停靠在左上角,Margin为 200,100,0,0 此时,

200 为 元素左边 与 父控件左边 的距离。

100 为元素上边 与 父控件上边 的距离。

只有200,100发挥作用,后面两个数字不发挥作用,也就是说

当 HorizontalAlignment="Left",Margin.Left 有效,Margin.Right 无效

当 VerticalAlignment =" Top ",Margin.Top有效,Margin.Bottom无效

以此类推。

 

第二类 全部居中,例如

    <TextBlock  Background="Orange" Text="Center+0,0,200,0" Opacity=".8"   HorizontalAlignment="Center"  Margin="0,0,200,0"  VerticalAlignment="Center"  />

如果margin 全为0,子元素 的中心点 与父元素的中心点重合。

Margin的四个值均发挥作用。

<以下内容为个人猜测,希望看官发表意见>

看上图,Text="Center+0,0,200,0" 的 桔黄色 区块。Margin.Right 为200 ,这个200是什么依据呢?

首先,Margin .Right 说明 距离父元素右边界200pix,也就是说,父元素右边界向左移动200像素。

然后 水平方向居中,总宽度700,减去刚才移动的200,剩下500,此时的水平中心点应该是250,原来的中心点是700/2=350,所以,桔黄色区块的中心点与父元素中心点偏离100.

也就说,margin.right/2= 中心点偏离的距离,其他以此类推。

<猜测结束,希望看官发表意见>

 

第三类,部分居中,例如。

 

        <TextBlock Background="Red" Text="Left+Center" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="100,100,0,0" />

 

水平方向上 左对齐,margin.left 有效,margin.right 无效

垂直方向上 居中,margin.top 和margin.bottom均有效。

具体算法,参照前两类。

 

第四类 伸展模式,例如

  <Label HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" Margin="445,54,123,358" Background="LightBlue"  >Stretch+Stretch+445,54,123,358</Label>

 

看右上角那个区块,就是此例子。

设置了Stretch后,

如果没有显式的设置尺寸,尺寸大小就有margin来决定了,父元素四个边界减去Margin对应的值就是子元素的尺寸,小心父元素变小后,子元素尺寸可能会变为0,不可见了。

如果设置了元素的尺寸,margin也在,尺寸优先,指定多大的尺寸就显示多大,Margin部分可能数值无效,

例如

    <Label HorizontalAlignment="Stretch"  Width="20" Height="100" VerticalAlignment="Stretch"  Margin="400,26,200,374"  Background="LightBlue"  >Stretch+Stretch+445,54,123,358</Label>

     总宽度700-400-200=100,按照margin,留给元素的宽度是100,因为Width="20",所以实际宽度为20,Margin.right 无效

 

但是,如果尺寸+margin >父元素的尺寸,以margin为准。例如

        <Label HorizontalAlignment="Stretch"  Width="200" Height="100" VerticalAlignment="Stretch"  Margin="400,26,200,374"  Background="LightBlue"  >Stretch+Stretch+445,54,123,358</Label>

父元素宽度为700 。

700-400-200 =100 只有100了!元素就只能显示100,Width =200无效

 

 

Over!

 源码如下:

 

    <Grid  >
        <Grid.Background>
            <RadialGradientBrush  SpreadMethod="Repeat">
                <RadialGradientBrush.GradientStops>
                    <GradientStop Offset="0.2"  Color="Green"/>
                    <GradientStop Offset="0.5"  Color="LightGreen" />
                </RadialGradientBrush.GradientStops>
            </RadialGradientBrush>
        </Grid.Background>
        <Grid.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Width" Value="100" />
                <Setter Property="Height" Value="50" />
                <Setter Property="TextWrapping" Value="Wrap" />
                <Setter Property="Padding" Value="5" />
            </Style>
        </Grid.Resources>
        <Rectangle Width="1" HorizontalAlignment="Center"  Fill="Red" />
        <Rectangle Width="1" HorizontalAlignment="Right" Margin="0,0,200,0"  Fill="Red"  />
        <Rectangle Width="1" HorizontalAlignment="Left" Margin="200,0,0,0"  Fill="Red"  />

        <Rectangle Height="1"  VerticalAlignment="Center" Fill="Red"  />
        <Rectangle Height="1" Margin="0,125,0,0"  VerticalAlignment="Top" Fill="Red"  />
        <Rectangle Height="1"  Margin="0,0,0,125"   VerticalAlignment="Bottom" Fill="Red"  />

        
        <TextBlock Background="Red" Text="Center"       HorizontalAlignment="Center"  Margin="0,0,0,0"  VerticalAlignment="Center" />

        <TextBlock  Background="AliceBlue" Text="Center+200,0,0,0"   HorizontalAlignment="Center"  Margin="200,0,0,0"  VerticalAlignment="Center"   />
        <TextBlock  Background="Orange" Text="Center+0,0,200,0" Opacity=".8"   HorizontalAlignment="Center"  Margin="0,0,200,0"  VerticalAlignment="Center"  />

        <TextBlock Background="Red" Text="Left+Center" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="100,100,0,0" />

        <TextBlock Background="Red" Text="Left+Top" HorizontalAlignment="Left" VerticalAlignment="Top" />
        <TextBlock Background="CadetBlue" Margin="200,0,0,0"     HorizontalAlignment="Left" VerticalAlignment="Top" Text="Left+Top+200,0,0,0" />
        <TextBlock Background="Azure" Margin="0,100,0,0"     HorizontalAlignment="Left" VerticalAlignment="Top" Text="Left+Top+0,100,0,0" />
        <TextBlock Background="Yellow" Margin="200,100,0,0"     HorizontalAlignment="Left" VerticalAlignment="Top" Text="Left+Top+200,100,0,0" />


        <TextBlock Background="Red" Text="Left+Bottom" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
        <TextBlock Background="Red" Margin="200,0,0,0" Text="Left+Bottom + 200,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
        <TextBlock Background="Azure" Margin="0,0,0,100" Text="Left+Bottom + 0,0,0,100" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
        <TextBlock Background="Azure" Margin="200,0,0,100" Text="Left+Bottom + 200,0,0,100" HorizontalAlignment="Left" VerticalAlignment="Bottom" />

        <TextBlock HorizontalAlignment="Right"  VerticalAlignment="Center"  Width="100" Height="50" Background="LightGoldenrodYellow"  >Right+Center</TextBlock>
        <TextBlock HorizontalAlignment="Right"  VerticalAlignment="Center" Margin="0,0,100,0" Width="100" Height="50" Background="Yellow"  >Right+Center+0,0,100,0</TextBlock>
        <TextBlock HorizontalAlignment="Right"  VerticalAlignment="Center" Margin="0,200,0,0" Width="100" Height="50" Background="LightBlue"  >Right+Center+0,200,0,0</TextBlock>
        <TextBlock HorizontalAlignment="Right"  VerticalAlignment="Center" Margin="0,200,100,0" Width="100" Height="50" Background="Yellow"  >Right+Center+0,200,100,0</TextBlock>


        <Label HorizontalAlignment="Stretch"  Width="200" Height="100" VerticalAlignment="Stretch"  Margin="400,26,200,374"  Background="LightBlue"  >Stretch+Stretch+445,54,123,358</Label>
     
    </Grid>
原文地址:https://www.cnblogs.com/xiaokang088/p/2032595.html