c# WPF 布局控件
c# WPF 布局控件
一、概论
WPF是继MFC和Winform后,下一代Windows 桌面应用程序的技术。其核心是一个与分辨率无关并且基于向量的程序引擎,以在现代图形硬件的优势下,实现更优质的用户客户端软件。
WPF的布局控件是继承于System.Windows.Controls.Panel这个类的,本文我们主要举例说明,在Panel基类下的几个常用的窗口布局控件。
二、 Canvas
Canvas面板是最轻量级的布局控件,元素按照默认大小显示在左上角,溢出的内容则会显示在Canvas外(可以将ClipToBounds属性设置为true来裁剪溢出内容)。下面是使用Canvas面板的XAML代码。
<Canvas Background="LightGray" Margin="10,10,10,64" >
<Rectangle Name="rect" Width="200" Height="200" Fill="#FF1BEA41"/>
<Rectangle Width="100" Height="300" Fill="#FF1131C3" Canvas.Left="321" Canvas.Top="100"/>
<Button Content="Button" Canvas.Left="499" Canvas.Top="25" Width="152" Height="37"/>
</Canvas>
效果如下:
Canvas Demo三、DockPanel
DockPanel中,可以使子元素通过锚点的形式进行排列,类似于WinForm中Dock属性的功能。
<DockPanel Margin="10" LastChildFill="True">
<Button Content="Top" DockPanel.Dock="Top"/>
<Button Content="Left" DockPanel.Dock="Left"/>
<Button Content="Right" DockPanel.Dock="Right"/>
<Button Content="Bottom" DockPanel.Dock="Bottom"/>
<Button Content="Btn1"/>
<Button Content="Btn2"/>
<Button Content="Btn3"/>
<Button/>
</DockPanel>
效果如下:
DockPanel Demo
四、Grid
Grid使用类似表格的布局方式,可以指定行列数量,以及分配对应大小。控件中的子元素会附加特定属性,由用户指定该子元素所在的行列位置,横跨方式等等。Grid 控件使用灵活,适合子元素多、布局复杂的场景:
<Grid Width="Auto" Height="Auto">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/> //固定值
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/> //比例值,去除固定宽度后按比例分到剩余空间的1/3
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Button Content="Btn1" Grid.RowSpan="2"/>
<Button Content="Btn2" Grid.Column="1" Grid.ColumnSpan="2"/>
<Button Content="Btn3" Grid.Row="1" Grid.Column="2"/>
<Button Content="Btn4" Grid.Row="1" Grid.Column="3"/>
</Grid>
效果如下:
Grid Demo
五、StackPanel
StackPanel控件是将子元素按照单行或单列的方式进行堆叠,可以通过Orientation参数,指定排列方向。下面对子元素设置不同参数进行展示:
<StackPanel Margin="10,10,10,10" Background="Azure">
<Button Content="Button"/>
<Button Content="Button" Width="200"/>
<Button Content="Button" Height="50"/>
<Button Content="Button" Margin="200,0,0,0" />
<Button Content="Button" Width="200" Margin="200,0,0,0" />
</StackPanel>
效果如下:
StackPanel Demo六、WrapPanel
WrapPanel控件按从左到右的顺序位置定位子元素,在包含框的边缘处将内容切换到下一行。 后续排序按照从上至下或从右至左的顺序进行,具体取决于方向Orientation属性的值。控件内部子元素布局会跟随控件大小变化自动调整,一般WrapPanel控件只用在小范围布局,控件大小也保持固定。
<WrapPanel Margin="10" Background="Azure">
<Button Content="Button" Height="50" Width="100"/>
<Button Content="Button" VerticalAlignment="Top"/>
<Button Content="Button" VerticalAlignment="Center"/>
<Button Content="Button" VerticalAlignment="Bottom"/>
<Button Content="Button"/>
<Button Content="Button" Width="100"/>
<Button Content="Button" Height="30" VerticalAlignment="Top"/>
<Button Content="Button" VerticalAlignment="Center"/>
<Button Content="Button" VerticalAlignment="Bottom"/>
<Button Content="Button"/>
</WrapPanel>
效果显示,单行高度由其中子元素高度属性最大值决定,并同时影响同列其他子元素的排列位置:
WrapPanel Demo七、UniformGrid
UniformGrid是Grid简化版本,不需要预先定义行和列,每个单元格具有相同大小。可以通过简单设置Rows和Columns属性来设置整体布局需求,或使用默认值0,使控件自动调整合适的布局。下面是添加四个元素后,控件自动分割为2*2的表格:
<UniformGrid>
<Button Content="Button" Width="100" Height="50"/>
<Button Content="Button" />
<Button Content="Button" />
<Button Content="Button" />
</UniformGrid>
将子元素数量增加,控件布局自动调整:
<UniformGrid>
<Button Content="Button" Width="100" Height="50"/>
<Button Content="Button" />
<Button Content="Button" />
<Button Content="Button" />
<Button Content="Button" />
</UniformGrid>
八、ScrollViewer
ScrollViewer控件可以方便地使应用程序中的内容具备滚动功能:
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto">
<Rectangle Width="500" Height="800"/>
</ScrollViewer>
效果如下:
ScrollViewer Demo九、自定义布局控件
要实现自定义布局控件,需要继承Panel类并重写MeasureOverride和ArrangeOverride方法。首先,自定义一个用户类:
using System.Windows;
using System.Windows.Controls;
namespace TestClass
{
public class TestPanel : Panel
public TestPanel(): base() {}
// 重写默认的Measure方法
protected override Size MeasureOverride(Size availableSize)
{
Size v_panelDesiredSize = new Size();
foreach (UIElement v_child in this.InternalChildren)
{
v_child.Measure(availableSize);
v_panelDesiredSize.Width += v_child.DesiredSize.Width;
v_panelDesiredSize.Height += v_child.DesiredSize.Height;
}
return v_panelDesiredSize;
}
// 重写默认的Arrange方法
protected override Size ArrangeOverride(Size finalSize)
{
double v_x = 10;
double v_y = 10;
foreach (UIElement v_child in this.InternalChildren)
{
v_child.Arrange(new Rect(new Point(v_x, v_y), new Size(200, v_child.DesiredSize.Height)));
v_y += v_child.RenderSize.Height + 5;
v_x += 5;
}
return finalSize;
}
}
}
添加自定义控件的程序集,及如下代码:
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mcontrol="clr-namespace:TestClass"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="277.5" Width="542">
<mcontrol:TestPanel Margin="0,0,266,143">
<Button Content="Button"/>
<Button Content="Button"/>
<Button Content="Button"/>
</mcontrol:TestPanel>
</Window>
效果如下:
自定义布局控件