布局(Layout)控件用于管理子元素的大小、尺寸、位置和排列方式。
边框(Border) Border
可以在另一个元素周围绘制边框与背景。
需要注意的是,Border
内最多只能有一个子级。
若要显示多个子元素,需要在父 Border
中放置其他 Panel 元素,可以将子元素放在该 Panel
元素中。
1 <Border Background ="LightBlue" BorderBrush ="Black" BorderThickness ="2" CornerRadius ="45" Padding ="25" />
子弹装饰器(BulletDecorator) BulletDecorator
是一个布局控件,该控件可以将项目符号与另一个可视对象对齐。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <StackPanel > <BulletDecorator Margin ="5" VerticalAlignment ="Center" Background ="Yellow" > <BulletDecorator.Bullet > <Image Width ="50" Source ="pack://application:,,,/WpfExample;component/images/bullet.png" /> </BulletDecorator.Bullet > <TextBlock TextWrapping ="Wrap" VerticalAlignment ="Center" HorizontalAlignment ="Left" Foreground ="Purple" > A Simple BulletDecorator</TextBlock > </BulletDecorator > <BulletDecorator Margin ="5" VerticalAlignment ="Center" Background ="Yellow" > <BulletDecorator.Bullet > <Image Width ="20" Source ="pack://application:,,,/WpfExample;component/images/apple.jpg" /> </BulletDecorator.Bullet > <TextBlock TextWrapping ="Wrap" VerticalAlignment ="Center" HorizontalAlignment ="Left" Foreground ="Purple" > A Simple BulletDecorator</TextBlock > </BulletDecorator > <BulletDecorator Margin ="5" VerticalAlignment ="Center" Background ="Yellow" > <BulletDecorator.Bullet > <Ellipse Margin ="5,0,0,0" Height ="10" Width ="10" Fill ="Purple" HorizontalAlignment ="Left" > </Ellipse > </BulletDecorator.Bullet > <TextBlock Margin ="10,0,0,0" TextWrapping ="Wrap" VerticalAlignment ="Center" HorizontalAlignment ="Left" Foreground ="Purple" > A Simple BulletDecorator</TextBlock > </BulletDecorator > <BulletDecorator Margin ="5" VerticalAlignment ="Center" Background ="Yellow" > <BulletDecorator.Bullet > <Ellipse Margin ="5,0,0,0" Height ="10" Width ="10" Fill ="Purple" HorizontalAlignment ="Left" > </Ellipse > </BulletDecorator.Bullet > <TextBlock Margin ="10,0,0,0" TextWrapping ="Wrap" VerticalAlignment ="Center" HorizontalAlignment ="Left" Foreground ="Purple" > A Simple BulletDecorator</TextBlock > </BulletDecorator > <BulletDecorator Margin ="5" VerticalAlignment ="Center" Background ="Yellow" > <BulletDecorator.Bullet > <CheckBox /> </BulletDecorator.Bullet > <TextBlock Margin ="10,0,0,0" TextWrapping ="Wrap" Width ="200" VerticalAlignment ="Center" HorizontalAlignment ="Left" Foreground ="Purple" > A very very veryvery very very very long text BulletDecorator</TextBlock > </BulletDecorator > </StackPanel >
如上代码所展示的是一个使用 BulletDecorator
控件实现一个无序列表。可以任意定义 Bullet
以及 Child
内的内容。
以上例子分别使用了图形与圆形放置在 Bullet
中作为列表的符号,Child
内容固定为一段文本内容,当文本换行时,文本的第一行将与列表符号对齐。
该控件除可以作为列表提供展示外,还可以在 Bullet
中放置单选框、多选框、输入框等。
Canvas(画布) 定义一个区域,可在其中使用相对于 Canvas
区域的坐标以显式方式来定位子元素。
1 2 3 4 5 <Canvas Height ="400" Width ="400" > <Canvas Height ="100" Width ="100" Top ="0" Left ="0" Background ="Red" /> <Canvas Height ="100" Width ="100" Top ="100" Left ="100" Background ="Green" /> <Canvas Height ="100" Width ="100" Top ="50" Left ="50" Background ="Blue" /> </Canvas >
需要注意的是 Canvas
作为一个存储控件的容器,其不会自动调整内部元素的大小与排列。
Canvas
默认也不会裁剪超出自身范围的内容,溢出的内容将会显示在 Canvas
外,可以通过通过调整 ClipToBounds
属性,来控制是否裁剪多出的内容。
停靠面板(DockPanel) 定义一个区域,从中可以按相对位置水平或垂直排列各个子元素。
1 2 3 4 5 6 7 8 9 10 11 <DockPanel > <Button DockPanel.Dock ="Top" Background ="Aqua" > 1(Top)</Button > <Button DockPanel.Dock ="Left" Background ="Green" > 2(Left)</Button > <Button DockPanel.Dock ="Right" Background ="Yellow" > 3(Right)</Button > <Button DockPanel.Dock ="Bottom" Background ="Blue" > 4(Bottom)</Button > <DockPanel Background ="Orange" LastChildFill ="False" > <Button Height ="20" > Button 1</Button > <Button Height ="20" > Button 2</Button > <Button DockPanel.Dock ="Right" Height ="20" > Button 3</Button > </DockPanel > </DockPanel >
SetDock
方法更改某个元素相对于同一容器中的其他元素的位置。对齐属性(如 HorizontalAlignment
)更改元素相对于其父元素的位置。
默认情况下 DockPanel
中的最后一个元素将填充剩余空间,而不考虑最后一个元素设置的任何其他 Dock
值,可以通过指定 LastChildFill
属性并设置停靠方向来调整。
默认情况下,Panel
元素不接收焦点。 若要强制 Panel
元素接收焦点,请将 Focusable
属性设置为 true
。
扩展器(Expander) Expander
是一个可以展开和折叠的控件,它包含标头 Header
和内容 Content
两个部分。
1 2 3 4 5 6 7 8 9 10 <Expander Background ="Tan" HorizontalAlignment ="Left" ExpandDirection ="Down" IsExpanded ="True" Width ="100" > <Expander.Header > <TextBlock > hd2y</TextBlock > </Expander.Header > <StackPanel HorizontalAlignment ="Center" > <TextBlock > <Hyperlink > 用户中心</Hyperlink > </TextBlock > <TextBlock > <Hyperlink > 博客</Hyperlink > </TextBlock > <TextBlock > <Hyperlink > 注销</Hyperlink > </TextBlock > </StackPanel > </Expander >
Content
和 Header
属性可以是任何类型(如字符串、图像或面板)。
如果展开窗口的内容对窗口而言太大,则可以将 Expander
的内容包装在 ScrollViewer
控件中以提供可滚动的内容。 Expander
控件不自动提供滚动功能。
网格(Grid) Grid
用来定义由列和行组成的灵活的网格区域。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <Grid VerticalAlignment ="Top" HorizontalAlignment ="Left" ShowGridLines ="True" Width ="250" Height ="100" > <Grid.ColumnDefinitions > <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions > <Grid.RowDefinitions > <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions > <TextBlock FontSize ="20" FontWeight ="Bold" Grid.ColumnSpan ="3" Grid.Row ="0" > 2005 Products Shipped</TextBlock > <TextBlock FontSize ="12" FontWeight ="Bold" Grid.Row ="1" Grid.Column ="0" > Quarter 1</TextBlock > <TextBlock FontSize ="12" FontWeight ="Bold" Grid.Row ="1" Grid.Column ="1" > Quarter 2</TextBlock > <TextBlock FontSize ="12" FontWeight ="Bold" Grid.Row ="1" Grid.Column ="2" > Quarter 3</TextBlock > <TextBlock Grid.Row ="2" Grid.Column ="0" > 50000</TextBlock > <TextBlock Grid.Row ="2" Grid.Column ="1" > 100000</TextBlock > <TextBlock Grid.Row ="2" Grid.Column ="2" > 150000</TextBlock > <TextBlock FontSize ="16" FontWeight ="Bold" Grid.ColumnSpan ="3" Grid.Row ="3" > Total Units: 300000</TextBlock > </Grid >
默认情况下列宽与行高是等比例分配,可以设置 Width
与 Height
属性为 Auto
让宽高自适应。
宽高除可以设置为 Auto
外,其默认值为 1*
,这里 *
会使用设定了固定值外的剩余空间,按前面设置的数值进行等比例分配。
固定值我们可以设置 100
、100px
、100pt
、100cm
、100in
,默认单位为 px
,所以 100
与 100px
是同样的。
在子元素中,我们可以通过设置 ColumnSpan
与 RowSpan
,让这个元素跨列或跨行显示。
网格拆分器(GridSplitter) 利用 Grid
我们可以很方便的划分单元格,并通过设定宽高来控制每行每列所占用的空间。
但是如果想要让用户来改变每行每列的宽高,就需要使用 GridSplitter
来实现这样的效果。
例如以下代码,定义了一个 GridSplitter
,通过覆盖列的边缘来调整 Grid 中列的大小:
1 2 3 4 5 6 7 <Grid > <Grid.ColumnDefinitions > <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions > <GridSplitter Grid.Column ="0" Background ="Blue" Width ="5" HorizontalAlignment ="Right" VerticalAlignment ="Stretch" /> </Grid >
而以下代码中,GridSplitter
将在 Grid
中占用一列:
1 2 3 4 5 6 <Grid.ColumnDefinitions > <ColumnDefinition Width ="2*" /> <ColumnDefinition Width ="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions > <GridSplitter Grid.Column ="1" HorizontalAlignment ="Center" VerticalAlignment ="Stretch" Background ="Black" ShowsPreview ="True" Width ="5" />
组框(GroupBox) GroupBox
控件可以在用户界面的内容外创建一个带有边框与标题的容器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <GroupBox > <GroupBox.Header > <Label > health information</Label > </GroupBox.Header > <Grid > <Grid.RowDefinitions > <RowDefinition Height ="30" /> <RowDefinition Height ="30" /> <RowDefinition /> </Grid.RowDefinitions > <Grid.ColumnDefinitions > <ColumnDefinition Width ="100" /> <ColumnDefinition /> </Grid.ColumnDefinitions > <Label VerticalAlignment ="Center" HorizontalAlignment ="Right" > height:</Label > <Label Grid.Row ="1" VerticalAlignment ="Center" HorizontalAlignment ="Right" > weight:</Label > <TextBox Grid.Row ="0" Grid.Column ="1" Margin ="3" > </TextBox > <TextBox Grid.Row ="1" Grid.Column ="1" Margin ="3" > </TextBox > </Grid > </GroupBox >
GroupBox
的效果类似 html
中的 fieldset
标签。
另外需要注意的是,GroupBox
是 HeaderedContentControl
,这意味着其 Content
和 Header
属性可以是任何类型(如字符串、图像或面板)。
分离器(Separator) Separator
控件是用来分隔控件中的多个项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <ToolBarTray Background ="White" > <ToolBar Band ="1" BandIndex ="1" > <Button > New</Button > <Button > Open</Button > <Button > Save</Button > <Separator /> <Button > Cut</Button > <Button > Copy</Button > <Button > Paste</Button > <Separator /> <Button > Print</Button > <Button > Preview</Button > </ToolBar > </ToolBarTray >
ScrollBar
提供一个滚动条的控件,其位置对应于值。
1 <ScrollBar Orientation ="Horizontal" Width ="4in" Value ="50" Minimum ="1" Maximum ="100" />
ScrollViewer
定义可滚动的区域,可以包含其他可见元素。
1 2 3 4 5 6 <ScrollViewer HorizontalScrollBarVisibility ="Auto" > <StackPanel VerticalAlignment ="Top" HorizontalAlignment ="Left" > <TextBlock TextWrapping ="Wrap" Margin ="0,0,0,20" > Scrolling is enabled when it is necessary. Resize the window, making it larger and smaller.</TextBlock > <Rectangle Fill ="Red" Width ="500" Height ="500" > </Rectangle > </StackPanel > </ScrollViewer >
堆栈面板(StackPanel) StackPanel
可以将子元素排列成水平或垂直的一行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <Grid > <Grid.RowDefinitions > <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions > <StackPanel > <Button > Test1</Button > <Button > Test2</Button > <Button > Test3</Button > </StackPanel > <StackPanel Grid.Row ="1" Orientation ="Horizontal" > <Button > Test4</Button > <Button > Test5</Button > <Button > Test6</Button > </StackPanel > </Grid >
默认子元素会垂直排列,可以修改 Orientation
属性为 Horizontal
,子元素将水平排列。
查看框(ViewBox) ViewBox
组件的作用是拉伸或延展位于其中的组件,使之有更好的布局及视觉效果。
1 2 3 <Viewbox Stretch ="Fill" StretchDirection ="Both" Width ="400" Height ="60" > <Button > 测试</Button > </Viewbox >
ViewBox
内只能有一个子元素,另外可以通过设置 Stretch
与 StretchDirection
属性,来设置内容的缩放效果。
Stretch
可选项有:
None
:原始大小。
Fill
:填充,子元素占满整个 Viewbox
,不保证宽高比例。
Uniform
:等比例缩放。在 Viewbox
能完整显示子元素的最大尺寸;
UniformToFill
:等比例缩放填充,子元素在保证缩放的情况下填充 Viewbox
,多余的部分被裁剪。
StretchDirection
可选项有:
Both
:内容根据 Stretch
模式进行缩放以适合父项的大小;
DownOnly
:内容仅在大于父级时缩放。如果内容较小,则不会执行任何缩放。
UpOnly
:内容仅在小于父级时缩放。如果内容较大,则不执行缩放。
窗口(Window) Window
提供了创建、配置、显示、管理窗口与对话框的生命周期的能力。
1 <Window xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title ="Main Window in Markup Only" Height ="300" Width ="300" />
用户与独立应用程序之间的交互点是一个窗口。WPF
窗口包含两个不同的区域:
承载 Windows
修饰的非工作区,包括图标、标题、系统菜单、最小化按钮、最大化按钮、还原按钮、关闭按钮和边框。
承载特定于应用程序的内容的工作区。
Window
封装了创建、配置、显示和管理窗口和对话框的声明周期的功能,并提供了以下关键服务:
生命周期管理:Activate
、Activated
、Close
、Closed
、Closing
、Deactivated
、Hide
、IsActive
、Show
、SourceInitialized
。
窗口管理:GetWindow
、OwnedWindowsOwner
。
外观和行为:AllowsTransparency
、ContentRendered
、DragMove
、Icon
、Left
、LocationChanged
、ResizeMode
、RestoreBounds
、ShowActivated
、ShowInTaskbar
、SizeToContent
、StateChanged
、Title
、Top
、Topmost
、WindowStartupLocation
、WindowState
、WindowStyle
。
对话框:DialogResult
,ShowDialog
。
此外,Application
公开了对管理应用程序中的所有窗口的特殊支持:应用程序维护当前在应用程序中实例化的所有窗口的列表。 此列表由 Windows
属性公开。
默认情况下,将使用对应用程序中实例化的第一个 Window
的引用自动设置 MainWindow
。 从而使窗口成为主应用程序窗口。
Window
主要用于显示独立应用程序的窗口和对话框。但是,对于需要在窗口级别导航的应用程序(如向导),可以改用 NavigationWindow
。NavigationWindow
派生自 Window
并通过浏览器样式的导航支持对其进行扩展。
注: 本文的目的是为了熟悉常见的布局控件,所以存在大段的复制粘贴。 示例代码来自 MSDN
,内容已经上传至 github
:hd2y/WpfExample
参考: