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,
}
在元素上显式设置 Height 和 Width 属性时,这些度量值在布局过程中将具有较高的优先级,并且取消将 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>