博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

WPF 布局

Posted on 2011-05-13 21:19  linFen  阅读(1050)  评论(0编辑  收藏  举报

WPF提供了丰富而灵活的布局机制,我们利用一些工具可以很方便的控制元素的布局格式。

1.      布局基础:

WPF提供了一组面板(panel)用于控制布局,每个面板都有自己的一些特性,你可以根据需要选择面板,或是组合或是嵌套面板从而灵活控制你的布局。

StackPanel:横向或是竖向排列子控件,常用于小范围排版场合

WrapPanel:类似于StackPanel,将子控件从左到右排列,不同的是当横向空间不够时,他会自动换到下一行。

DockPanel:类似于Winform中的Dock属性,将子控件贴在某个方向上。

Grid :将子控件排列于行和列中,可以灵活的定义行列的宽度和跨度

UniformGrid:类似于Grid,不过每个单元格的大小是相同的.

Canvas:以坐标的方式控制子控件的位置,唯一一种可以完全控制位置的方式。

 

2.      StackPanel布局:

StackPanle就是简单的将内容横向或是竖向排成一列,通过Orientation="Horizontal"属性设置,默认是vertical竖向排列。例如:

<StackPanel Background="#ECE9D8">

<TextBlock Margin="3">Look for:</TextBlock>

<ComboBox Margin="3"/>

<TextBlock Margin="3">Filtered by:</TextBlock>

<ComboBox Margin="3"/>

<Button Margin="3,5">Search</Button>

<CheckBox Margin="3">Search in titles only</CheckBox>

<CheckBox Margin="3">Match related words</CheckBox>

<CheckBox Margin="3">Search in previous results</CheckBox>

<CheckBox Margin="3">Highlight search hits (in topics)</CheckBox>

</StackPanel>

产生效果如图:

 

 

其中Margin类似于Css中的margin元素,设置元素的浮动情况,是公共布局属性的一部分,在后面会提到。在上面一张效果图中我们可以看到TextBlock控件和CheckBox控件都是很自然的显示在一行,但是Search按钮却显的很宽,非常的不好看,这是因为默认情况下StackPanel是将所有子控件都是和Panel同宽或是同高的,这里所有子控件的宽度都是和StackPanel同宽的。为了控制子控件的宽度或高度,可以设置HorizontalAlignmentVerticalAlignment属性,当竖向排版时设置HorizontalAlignment,可设置为leftrightcenterStretch,横向排版时设置VerticalAlignment属性,可设置为TopButtomCenterStretch,本例中设置HorizontalAlignmentLeft

<Button Margin="3,5" HorizontalAlignment="Left">Search</Button>

 

按钮就会保持原来自己的宽度,然后左对齐到StackPanel中,如果设置Centerright同样,会对齐到中间或是右边。

横向排版例子:

<StackPanel Orientation="Horizontal">

<TextBlock>This is some text</TextBlock>

<Button>Button</Button>

<Button>Button (different one)</Button>

<CheckBox>Check it out</CheckBox>

<TextBlock>More text</TextBlock>

</StackPanel>

StackPanel在内容大于Panel的时候处理不够灵活,通常会阶段多出的控件,相比而言,WrapPanel就要聪明很多。

 

3.      WrapPanel布局:

WrapPanelStackPanel非常类似,只有在子控件超出Panel范围时有所不同,WrapPanel会换行,就像在Word里面打字一样,当字数超过一行的范围时就会自动跳转到下一行:

<WrapPanel Background="Beige">

<Button>One</Button>

<Button>Two</Button>

<Button>Three</Button>

<Button>Four</Button>

<Button>Five</Button>

<Button>Six</Button>

<Button>Seven</Button>

<Button>Eight</Button>

</WrapPanel>

 

WrapPanel同样有Orientation属性,用于设置子控件的排列方向。

WrapPanelStackPanel在小规模排版中非常常见,但是当你在复杂的场合时,可能需要更强大的排版工具,下面会一一介绍。

 

4.      DockPanel布局:

DockPanel在全局布局中非常有用,它通常用于整个界面的划分,然后通过其他布局控件来做细节的布局。

DockPanel将子控件“贴”在某个边上,如果多个子控件同时设置到一个方向,默认情况下,先设置的越靠近边界,后面的子控件占用剩下的空间。我们先看个例子:

<DockPanel>

<Button DockPanel.Dock="Top">Top</Button>

<Button DockPanel.Dock="Bottom">Bottom</Button>

<Button DockPanel.Dock="Left">Left</Button>

<Button DockPanel.Dock="Right">Right</Button>

<Button>Fill</Button>

</DockPanel>

 

这个例子使用了DockPanel.Dock,这其实是属于XAML中的Attached Properties(附加属性)语法。

关于附加属性:WPF中有些需求像DockPanel就是要将某个子控件排列到某个边上,处理的方式最自然的就是使用一个基类拥有一个Dock属性,然后DockPanel继承自这个基类,通常情况下可以解决这个问题,但是对于其他Panel来说却有些凌乱,因为其他panel不需要dock属性, 而且这个方案还缺乏灵活性,假如你需要创建一个新的自定义panel需要实现新的布局需求时,你需要添加新的属性来满足你的需求。XAML语法中的附加属性就是解决这个问题的方案,附件属性可以让控件元素的属性附加另外的元素。DockPanel定义了Dock属性并且可以被任何子控件附件,这样他的任何子元素都可以设置自己的Dock属性。

 

四个控件分别被设置为靠上面,下面,左边和右边,最后一个控件占据最后剩下的空间。Topbuttom控件占据了边界的整个宽度,而leftright却没有,这是因为TopButtom两个控件是最先加入的,所以最先占据了整个宽度,而leftright只能占据剩下的空间,如果我们替换下位置,情况就相反了:

 

<DockPanel>

<Button DockPanel.Dock="Left">Left</Button>

<Button DockPanel.Dock="Right">Right</Button>

<Button DockPanel.Dock="Top">Top</Button>

<Button DockPanel.Dock="Bottom">Bottom</Button>

<Button>Fill</Button>

</DockPanel>

 

DockPanel里的内容不会重叠,后面的控件只会占据余下的空间,默认情况下,最后一个控件将占据所有剩下的控件,例如图中的fill控件,但是也可以设置LastChildFill属性为false(默认为true)让他保持自己的大小,默认会排列在左边,从而留下中间的空间。

设置为topbottom的控件宽度会填充到所有空间,例如上图,top控件会填充所有能填充的宽度,直到leftright控件,但是他们的高度是根据内容决定的,如果一行字符,高度就是一个字符,如果存在两行字符,高度就会变大。同样设置为leftright的控件在高度是固定的,填充全部高度,但是宽度是根据内容决定的。

DockPanel在全局规划中非常有用,例如你需要设计一个菜单栏或是工具栏,那么就在top放置一个DockPanel作为菜单或是工具栏,而剩下的由其他控件填充。