WPF入门(八)布局(layout)
WPF的布局很有意思,不在是winform那样的绝对像素位置。而是相对于其容器控件的路径。如果要指定位置,则要使用其父容器控件的属性来设置,然后,因为该控件在他的父容器控件内,所有他就具有了其父容器控件的某些属性,这叫做Atteched Property.附加属性。这是个很有意思(特点)的东西。我们先做个demo。代码如下:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="298" Width="615">
<Grid>
<Border Name="border1" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="2" BorderBrush="Black" Background="LightGray">
<Canvas Height="100" Name="canvas1" Width="200" >
<TextBlock Canvas.Left="27" Canvas.Top="27" Height="18" Name="textBlock1" Width="52" Text="lable:" />
</Canvas>
</Border>
</Grid>
</Window>
效果:
我们只是添加一个Canvas,并为它增加了一个边框Border.很简单吧。如果在 winform里要做到这个效果,则要继承后,在重载OnPaint方法,使用Grphics来重绘了。我们看看这个TextBlock 位置是如何指定的:
<TextBlock Canvas.Left="27"
奇怪的标记吧,这样的标记方式我们会经常用到。TextBlock位于Canvas容器下,所以他就具有了属性Canval.Left来表示自己位于Canvas内的位置,就左侧位置27。这个27不像winfrom那样是27个象素点,而是标识27个单位。
--------------------------------------------------------
经常我们还会遇到图层遮盖的问题,就是后一个图层遮盖前一个图层。类似下面:
我们看看代码
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="302" Width="622">
5 <Canvas Width="442" Height="248">
6 <Rectangle Width="100" Height="100" Canvas.Top="12" Canvas.Left="12" Fill="blue" />
7 <Rectangle Width="100" Height="100" Canvas.Top="62" Canvas.Left="62" Fill="yellow" />
8 <Rectangle Width="100" Height="100" Canvas.Top="98" Canvas.Left="133" Fill="green" />
9 </Canvas>
10 </Window>
想让图册不被遮盖,图层的z-index属性设置一下就可以了,比如Panel.ZIndex="1" 。z-index 越大,位于的图层越高,越不容易别遮盖。
<Rectangle Width="100" Height="100" Canvas.Top="62" Canvas.Left="62" Fill="yellow" Panel.ZIndex="1" />
-------------------------------------------------
注意:父容器默认情况下会根据子容器的大小来确定自身的大小,并且子控件默认(如果不设置子控件的宽和高)填充整个父容器控件大小。
让我们看看dockPanel容器控件,代码:
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window2" Height="304" Width="745">
5 <DockPanel Name="dockPanel1" >
6 <Border BorderThickness="2" BorderBrush="AliceBlue" DockPanel.Dock="Top">
7 <TextBlock Name="text1">Dock="top"</TextBlock>
8 </Border>
9 <Border BorderThickness="2" BorderBrush="Beige" DockPanel.Dock="Bottom">
10 <TextBlock Name="text4">dock="boottom"</TextBlock>
11 </Border>
12 <Border BorderThickness="2" BorderBrush="Aqua" DockPanel.Dock="Left">
13 <TextBlock Name="text2">Dock="left"</TextBlock>
14 </Border>
15 <Border BorderThickness="2" BorderBrush="Black" DockPanel.Dock="Right" Visibility="Hidden">
16 <TextBlock Name="text3">Dock="Right"</TextBlock>
17 </Border>
18 <Border BorderThickness="2" BorderBrush="BlueViolet" >
19 <TextBlock Name="text5" TextWrapping="WrapWithOverflow">dock="Fill", 默认最后一个子控件为Fill,忽略最后一个子控件的Dock属性设置。DockPanel的属性LastChildFill="False",可改变此设置</TextBlock>
20 </Border>
21 </DockPanel>
22 </Window>
23
注:第19行TextBlock.TextWrapping=WrapWithOverflow是为了让TextBlock自动换行。
Dockpanel默认最后一个子控件为Fill,而子控件在设置dock方式时(DockPanel.Dock = xxx),找不到Fill项,只有上下左右个方向的。那么如何控制DockPanel的各个块份的收缩呢,注意第15行,Border的Vsibility= hidden,这个是隐藏了当前控件。但是呢,并没有实现收缩的效果,该 Border虽然hidden了,但是仍然占位。使用Visibility = "Collapsed" 来完成收缩的效果。这个控件还无法做到wenfeiluo.dockpanel那样的效果,想要那样的效果,还需要我们自己想办法了。