目录
[VirtualizingStackPanel 类](#VirtualizingStackPanel 类)
布局控件
布局控件概述
在C#中使用WPF(Windows Presentation Foundation)进行布局控件时,你可以利用XAML(Extensible Application Markup Language)和代码来创建灵活、响应式的用户界面。WPF提供了多种布局控件,可以帮助你轻松地管理和设计界面布局。
以下是一些常用的WPF布局控件以及它们的概述:
- Grid(网格):网格控件允许你创建灵活的行和列布局,可以将控件按照网格中的行和列进行排列。
- StackPanel(堆栈面板):堆栈面板控件允许你按照水平或垂直方向对控件进行堆叠排列,依次放置在同一个方向上。
- WrapPanel(自动换行面板):自动换行面板控件类似于堆栈面板,但是在控件放置到一行后会自动换行,适用于需要动态添加并且自动换行的布局。
- DockPanel(停靠面板):停靠面板控件允许你将子控件停靠在父容器的边缘,可以停靠在上、下、左、右或者中间。
- UniformGrid(均匀网格):均匀网格控件类似于网格,但是所有单元格的大小都是相同的。
- Canvas(画布):画布控件允许你使用绝对坐标进行子控件的定位,适用于需要精确布局的场景。
- Border(边框):边框控件可以用于装饰其他控件,可以设置边框和背景颜色等属性。
这里面除了Border控件,其它控件都继承于Panel基类。
Panel基类
命名空间:
程序集:
PresentationFramework.dll
Panel类是WPF中所有布局控件的基类,由于其抽象性质,不能直接实例化,但是作为基类,它为所有的布局控件提供了一些共同的属性和方法,包括但不限于:
- Background 属性:允许设置控件的背景颜色或背景画刷。
- Children 属性:表示控件包含的子元素集合,可以通过此属性进行子元素的增删查改操作。
- IsItemsHost 属性:指示该 Panel 是否用作 ItemsControl 的主要容器。如果设置为 true,则表示此 Panel 是 ItemsControl 的主要容器,ItemsControl 在渲染其内容时会考虑到这一点。
- ZIndex 属性:控制子元素的层叠顺序,用于指定子元素在同一 Panel 中的绘制顺序。
- LogicalOrientation 和 HasLogicalOrientation 属性:逻辑方向属性,用于指示 Panel 的布局方向。例如,StackPanel 的逻辑方向可以是水平或垂直。
除了上述属性之外,Panel 类也提供了一些保护和虚拟方法,供子类进行重写以实现特定的布局逻辑。通过 Panel 类提供的这些属性和方法,派生类可以实现各种不同的布局方式,从而满足不同的应用需求。
官方文档:
Panel 类 (System.Windows.Controls) | Microsoft Learn
Grid控件(网格布局)
Grid控件是WPF中最常用的布局控件之一,它提供了一个灵活的网格布局系统,可以将界面划分为行和列,并在这些行和列的交叉点上放置子控件。
Grid控件的核心是其两个重要属性:ColumnDefinitions 和 RowDefinitions。这两个属性分别定义了网格布局中的列和行的集合。每个集合中的元素都是 ColumnDefinition 或 RowDefinition 类型的对象,它们允许你定义列和行的大小、最小大小、最大大小等属性,从而实现对网格布局的更精细控制。
通过设置子控件的 Grid.Column 和 Grid.Row 属性,可以指定子控件应该放置在网格的哪一列和哪一行。此外,通过设置 Grid.ColumnSpan 和 Grid.RowSpan 属性,还可以指定子控件应该跨越多少列和多少行。
一、左右排列
要在WPF中实现左右排列,可以使用Grid或者其他适合的布局控件。
下面是使用Grid控件实现左右排列的简单示例:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<!-- 左侧列 -->
<ColumnDefinition />
<!-- 右侧列 -->
</Grid.ColumnDefinitions>
<!-- 左侧内容 -->
<TextBlock Background="LightGray" Text="左侧内容" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0" />
<!-- 右侧内容 -->
<TextBlock Background="LightGray" Text="右侧内容" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1" />
</Grid>
</Window>
二、上下排列
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<!-- 上方行 -->
<RowDefinition Height="*" />
<!-- 下方行 -->
</Grid.RowDefinitions>
<!-- 上方内容 -->
<TextBlock Background="LightGray" Text="上方内容" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0" />
<!-- 下方内容 -->
<TextBlock Background="LightGray" Text="下方内容" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" />
</Grid>
</Window>
在这个示例中,我们使用了一个包含两行的Grid控件,每行的高度都设置为"*",表示均匀分配剩余空间。然后在每行中放置了一个TextBlock控件,分别表示上方内容和下方内容。通过设置Grid.Row属性,我们指定了每个TextBlock应该位于哪一行。
三、上下左右排列
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="左上角" Panel.ZIndex="1" Margin="20" />
<Button Grid.Row="0" Grid.Column="1" Content="右上角" Panel.ZIndex="0" Margin="20" />
<Button Grid.Row="1" Grid.Column="0" Content="左下角" Panel.ZIndex="1" Margin="20" />
<Button Grid.Row="1" Grid.Column="1" Content="右下角" Panel.ZIndex="0" Margin="20" />
</Grid>
</Window>
四、跨列排列
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="跨列" Panel.ZIndex="1" Margin="20" Grid.ColumnSpan="2"/>
<Button Grid.Row="1" Grid.Column="0" Content="左侧" Panel.ZIndex="1" Margin="20" />
<Button Grid.Row="1" Grid.Column="1" Content="右侧" Panel.ZIndex="0" Margin="20" />
</Grid>
</Window>
五、固定列宽
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="WPF1" Panel.ZIndex="1" Margin="20" />
<Button Grid.Row="0" Grid.Column="1" Content="WPF2" Panel.ZIndex="0" Margin="20" />
<Button Grid.Row="1" Grid.Column="0" Content="WPF3" Panel.ZIndex="1" Margin="20" />
<Button Grid.Row="1" Grid.Column="1" Content="WPF4" Panel.ZIndex="0" Margin="20" />
</Grid>
</Window>
六、调整行高和列宽
了解如何调整Grid控件的行高和列宽是设计出良好布局的关键。在WPF中,可以使用不同的方式来设置行高和列宽,包括绝对设置尺寸、自动设置尺寸以及按比例设置尺寸。
以下是这些设置方式的说明:
- 绝对设置尺寸: 使用设备无关单位准确地设置尺寸,通常是指定一个实际的数字(像素)作为宽度或高度。例如,<ColumnDefinition Width="100"></ColumnDefinition> 表示该列的宽度为100个设备无关单位。
- 自动设置尺寸: 使用值为Auto的方式来设置尺寸,这意味着行或列的尺寸会根据其中内容的大小自动调整,以满足内容的最小需要。例如,<ColumnDefinition Width="Auto"></ColumnDefinition> 表示该列的宽度将根据其中的内容自动调整。
- 按比例设置尺寸: 使用值为或N的方式来设置尺寸,这意味着将空间按比例分配给一组行或列。通常,表示尽可能大的值,而N表示将空间分配给一组行或列中的某一部分,N是权重值。例如,<ColumnDefinition Width="*"></ColumnDefinition> 表示该列的宽度将尽可能大,而<ColumnDefinition Width="2*"></ColumnDefinition> 表示该列的宽度是前一个列宽度的两倍。
七、Grid显示网格线
要在WPF的Grid中显示网格线,可以通过设置Grid控件的ShowGridLines属性为True来实现。这样设置后,Grid控件将在界面上显示出网格线,方便布局调整和调试。
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="WPF1" Panel.ZIndex="1" Margin="20" />
<Button Grid.Row="0" Grid.Column="1" Content="WPF2" Panel.ZIndex="0" Margin="20" />
<Button Grid.Row="1" Grid.Column="0" Content="WPF3" Panel.ZIndex="1" Margin="20" />
<Button Grid.Row="1" Grid.Column="1" Content="WPF4" Panel.ZIndex="0" Margin="20" />
</Grid>
</Window>
总结
Grid控件确实是WPF中最灵活、功能最强大的布局控件之一。它的自适应特性使得它在不同分辨率的屏幕上都能够良好地适应,并且其ActualWidth和ActualHeight属性提供了当前实际的宽度和高度,为布局和界面调整提供了极大的便利性。
UniformGrid控件(均分布局)
UniformGrid和Grid有些相似,UniformGrid和Grid都是用于在WPF中进行布局的面板控件。两者都可以划分为行和列,并在交叉点上放置控件。
只不过UniformGrid的每个单元格面积都是相等的,无论是横向的单元格还是纵向的单元格,它们都会平分整个UniformGrid。这意味着UniformGrid中的所有行和列都具有相同的大小。而在Grid中,每个行和列的大小可以根据需要设置为不同的值,可以是固定值、自动调整大小或者按比例分配剩余空间。
所以,
- 当你希望控件在UniformGrid中均匀分布,并且每个单元格具有相同的大小时,可以使用UniformGrid。这在需要显示一组控件,但不需要复杂布局的情况下非常有用。
- 如果你需要更复杂的布局,例如控件在行和列中具有不同的大小或者需要使用合并单元格等功能,那么应该使用Grid来实现。
代码示例:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<UniformGrid Rows="3" Columns="3" Width="300" Height="300" Background="LightGray">
<Button Content="Button 1" Margin="5"/>
<Button Content="Button 2" Margin="5"/>
<Button Content="Button 3" Margin="5"/>
<Button Content="Button 4" Margin="5"/>
<Button Content="Button 5" Margin="5"/>
<Button Content="Button 6" Margin="5"/>
<Button Content="Button 7" Margin="5"/>
<Button Content="Button 8" Margin="5"/>
<Button Content="Button 9" Margin="5"/>
</UniformGrid>
</Window>
在这个示例中,我们创建了一个包含3行和3列的UniformGrid,其中的每个单元格都会平均分配整个UniformGrid的宽度和高度。然后,我们在UniformGrid中放置了9个Button控件,它们会自动填充到UniformGrid的每个单元格中,并且每个Button控件之间会有一定的间距(通过Margin属性设置)。
UniformGrid会根据其自身的大小和行列数来平均分配空间给其中的子控件,从而实现均匀分布的布局效果。
StackPanel控件(栈式布局)
StackPanel是一个用于水平或垂直堆叠子元素的布局控件,在WPF中经常用于简单的布局需求。
以下是StackPanel的一些关键特性:
- 堆叠方向: StackPanel可以按照水平(Horizontal)或垂直(Vertical)方向堆叠其子元素。你可以通过设置StackPanel的Orientation属性来指定堆叠方向,其默认值为Vertical(垂直堆叠)。
- Children属性: 与其他面板控件类似,StackPanel也有一个Children属性,用于添加和管理其子元素。这些子元素会按照堆叠方向依次排列。
- 自适应大小: StackPanel会根据其子元素的大小自动调整自身的大小以适应内容。在水平堆叠模式下,StackPanel的宽度会根据最宽的子元素来确定;在垂直堆叠模式下,StackPanel的高度会根据最高的子元素来确定。
- 嵌套使用: StackPanel可以嵌套使用,从而实现更复杂的布局效果。例如,可以在一个StackPanel中包含多个垂直StackPanel,或者在一个垂直StackPanel中包含多个水平StackPanel,以实现更灵活的布局。
代码示例:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<StackPanel Orientation="Horizontal">
<Button Content="Button 1" Margin="5"/>
<Button Content="Button 2" Margin="5"/>
<Button Content="Button 3" Margin="5"/>
<Button Content="Button 4" Margin="5"/>
<Button Content="Button 5" Margin="5"/>
<Button Content="Button 6" Margin="5"/>
<Button Content="Button 7" Margin="5"/>
</StackPanel>
</Window>
WrapPanel控件(瀑布流布局)
WrapPanel是用于在WPF中实现自动换行布局的面板控件。它会将其子控件从左到右的顺序排列,如果一行的空间不足以显示下一个子控件,则会自动换行并继续在下一行显示剩余的子控件。
WrapPanel的主要特点包括:
- 自动换行布局: WrapPanel会根据可用空间动态地调整子控件的位置,如果一行的空间不够,就会自动换行。
- 方向性: WrapPanel默认是从左到右的水平排列,但也可以通过设置Orientation属性来指定垂直排列(可以按照水平(Horizontal)或垂直(Vertical)方向)。
- 自适应大小: WrapPanel会根据其子控件的大小自动调整自身的大小以适应内容,可以根据子控件的大小和数量来动态调整WrapPanel的大小。
- 适用性: WrapPanel适用于需要显示大量子控件,并且希望以自动换行的方式来显示这些子控件的场景,比如标签云、图片墙等。
扩展:
HorizontalAlignment是一个用于控制元素水平对齐方式的属性,在WPF中可以用于多种容器控件,包括WrapPanel。这个属性可以设置为以下几个值:
- Left(默认值): 元素左对齐。
- Center: 元素居中对齐。
- Right: 元素右对齐。
- Stretch: 元素拉伸以填充父容器的可用空间,这意味着元素将填充整个水平空间。
以下是一个简单的示例,演示了如何使用WrapPanel来实现自动换行布局:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<WrapPanel Orientation="Vertical" HorizontalAlignment="Left">
<Button Content="Button 1" Margin="5"/>
<Button Content="Button 2" Margin="5"/>
<Button Content="Button 3" Margin="5"/>
<Button Content="Button 4" Margin="5"/>
<Button Content="Button 5" Margin="5"/>
<Button Content="Button 6" Margin="5"/>
<Button Content="Button 7" Margin="5"/>
</WrapPanel>
</Window>
DockPanel控件(停靠布局)
DockPanel控件是用于停靠布局的面板控件,在WPF中经常用于将子元素按照相对位置水平或垂直排列。DockPanel可以将子元素停靠在其区域的左侧、右侧、顶部、底部或者中间,根据子元素设置的DockPanel.Dock属性来确定停靠的位置。
以下是DockPanel的一些关键特性:
- 停靠位置: 子元素可以停靠在DockPanel的左侧(Left)、右侧(Right)、顶部(Top)、底部(Bottom)或者中间(Center)。你可以通过设置子元素的DockPanel.Dock属性来指定停靠的位置。
- 停靠顺序: 当多个子元素设置了不同的停靠位置时,它们将按照从上到下、从左到右的顺序停靠。先设置的子元素会优先停靠在更靠近的位置。
- 填充剩余空间: 如果某个子元素没有设置停靠位置,它将填充DockPanel剩余的空间。这意味着只有一个子元素没有设置停靠位置时,它将占据DockPanel的所有剩余空间;当多个子元素都没有设置停靠位置时,它们将重叠显示。
- 自适应大小: DockPanel会根据其子元素的大小自动调整自身的大小以适应内容。停靠的子元素会根据停靠位置的不同而自动调整其大小和位置。
扩展:
DockPanel控件的LastChildFill属性用于控制最后一个未设置停靠位置的子元素是否填充剩余空间。当LastChildFill属性设置为True时(默认值),最后一个未设置停靠位置的子元素将填充DockPanel的剩余空间;当设置为False时,最后一个未设置停靠位置的子元素不会填充剩余空间,而是根据自身大小进行布局。
XML
<DockPanel LastChildFill="False" VerticalAlignment="Top">
设置LastChildFill="False"表示最后一个未设置停靠位置的子元素不会填充DockPanel的剩余空间。而VerticalAlignment="Top"则是将DockPanel在其父元素中垂直对齐到顶部。
下面是一个简单的示例,演示了如何使用DockPanel来实现停靠布局:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<DockPanel>
<Button Content="顶部" DockPanel.Dock="Top"/>
<Button Content="底部" DockPanel.Dock="Bottom"/>
<Button Content="左部" DockPanel.Dock="Left"/>
<Button Content="右部" DockPanel.Dock="Right"/>
<Button Content="中间"/>
</DockPanel>
</Window>
VirtualizingStackPanel 类
VirtualizingStackPanel是用于在水平或垂直方向上排列和显示内容的面板控件,它和StackPanel在用法上非常相似。VirtualizingStackPanel的一个重要特性是它支持虚拟化,这意味着它能够在处理大量数据时进行优化,只会实际呈现在界面上可见区域内的内容,而不是一次性呈现所有数据。
VirtualizingStackPanel继承自VirtualizingPanel抽象类,而VirtualizingPanel又继承自Panel布局基类。这种继承关系确保了VirtualizingStackPanel具有与其他面板控件相似的布局功能,同时也提供了对虚拟化和大数据集的支持。
由于VirtualizingStackPanel支持虚拟化,因此在处理大量数据时,它的性能通常比普通的StackPanel要好。特别是在列表或者数据绑定场景中,使用VirtualizingStackPanel可以显著减少内存占用和提高界面的响应速度。
代码示例:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid>
<ListBox x:Name="listBox" VirtualizingStackPanel.IsVirtualizing="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</Window>
cs
using System.Windows;
using System.Windows.Controls;
namespace WpfApp2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// 添加大量数据项
for (int i = 0; i < 1000; i++)
{
ListBoxItem item = new ListBoxItem();
item.Content = "Item " + i;
listBox.Items.Add(item);
}
}
}
}
启用ListBox中虚拟化的常用方式。通过将ListBox的ItemsPanel设置为VirtualizingStackPanel,并将VirtualizingStackPanel的IsVirtualizing属性设置为True,可以启用ListBox中的虚拟化功能。
ListBox默认使用VirtualizingStackPanel作为其ItemsPanel,这使得ListBox在处理大量数据时具有较好的性能表现。虚拟化技术使ListBox仅呈现在可见区域内的数据项,而不是一次性呈现所有数据,从而减少内存占用和提高界面响应速度。
Canvas控件(绝对布局)
Canvas 控件在 WPF 中提供了绝对布局的功能,允许我们像在 WinForms 中一样,通过拖拽子控件来进行布局。在 Canvas 中,子控件的位置是相对于 Canvas 控件本身的坐标系进行定位的,因此称为绝对布局。
Canvas 控件允许我们在其中放置各种子控件,并且可以通过设置子控件的 Canvas.Left 和 Canvas.Top 属性来确定子控件相对于 Canvas 控件左上角的位置。这样一来,我们可以精确地控制每个子控件的位置和大小,从而实现自由灵活的布局效果。
以下是一个简单的示例,演示了如何使用 Canvas 控件进行绝对布局:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Canvas Width="400" Height="300">
<Button Content="Button 1" Width="100" Height="30" Canvas.Left="50" Canvas.Top="50"/>
<Button Content="Button 2" Width="100" Height="30" Canvas.Left="200" Canvas.Top="100"/>
<Button Content="Button 3" Width="100" Height="30" Canvas.Left="100" Canvas.Top="200"/>
</Canvas>
</Window>
在这个示例中,我们创建了一个 Canvas 控件,并在其中放置了三个 Button 控件。通过设置每个 Button 控件的 Canvas.Left 和 Canvas.Top 属性,我们可以确定它们在 Canvas 中的位置。因此,Button 1 位于 (50, 50) 的位置,Button 2 位于 (200, 100) 的位置,Button 3 位于 (100, 200) 的位置。
Border控件(边框布局)
Border 控件并不是一个布局控件,而是一个装饰控件,它用于给其内部的子元素提供边框和背景等装饰效果。Border 控件的作用是在其内部容纳一个单一的子元素,并为这个子元素提供装饰效果,例如边框和背景色。
Border 控件属于 Decorator 控件的一种,Decorator 控件是一种特殊的控件,用于在其内部容纳一个单一的子元素,并为这个子元素提供装饰或效果。Decorator 控件继承自 FrameworkElement,而不是 Panel 控件。
因此,虽然我们可以使用 Border 控件来为子元素提供装饰效果,但它并不是一个布局控件,而是一个装饰控件。在使用 Border 控件时,我们应该意识到它的作用是为子元素提供装饰效果,而不是用来进行布局。
Border 控件具有一些常用的属性,用于定义其边框、填充和背景等装饰效果。以下是这些属性的说明:
- BorderThickness(边框厚度):用于设置 Border 边框的厚度,即边框的宽度。它是一个 Thickness 类型的属性,可以指定四个方向的边框厚度。
- Padding(填充):用于设置子元素相对于 Border 边框的内边距,即子元素与 Border 边框之间的距离。它是一个 Thickness 类型的属性,可以指定四个方向的填充距离。
- CornerRadius(圆角):用于设置 Border 边框的圆角半径,即边框的四个角可以设置为圆角。它是一个 CornerRadius 类型的属性,可以分别设置四个角的圆角半径。
- BorderBrush(边框颜色):用于设置 Border 边框的颜色,即边框的绘制颜色。它是一个 Brush 类型的属性,可以是 SolidColorBrush、GradientBrush 等画刷类型。
- Background(背景颜色):用于设置 Border 的背景颜色,即 Border 控件的填充颜色。它是一个 Brush 类型的属性,可以是 SolidColorBrush、GradientBrush 等画刷类型。
代码示例
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Canvas Width="400" Height="300">
<Border BorderThickness="2"
BorderBrush="Black"
Background="LightGray"
CornerRadius="5"
Padding="10" Canvas.Left="86" Canvas.Top="130">
<TextBlock Text="这是一个带边框和圆角的填充文本块。"/>
</Border>
</Canvas>
</Window>
在这个示例中,我们创建了一个 Border 控件,其中包含一个 TextBlock 子元素。Border 控件具有以下属性设置:
- BorderThickness="2":设置边框的厚度为 2 个像素。
- BorderBrush="Black":设置边框的颜色为黑色。
- Background="LightGray":设置背景的颜色为浅灰色。
- CornerRadius="5":设置边框的圆角半径为 5 个像素,即边框的四个角都是圆角。
- Padding="10":设置填充距离为 10 个像素,即子元素与边框之间的距离为 10 个像素。
在 Border 控件内部,我们放置了一个 TextBlock 控件,用于显示文本内容。这样,我们就创建了一个具有边框、填充和圆角的装饰效果的 UI 元素。
GridSplitter分割窗口
GridSplitter 控件用于分割 Grid 栅格布局,允许用户通过鼠标拖动来调整行列尺寸,实现布局的灵活性。GridSplitter 必须放置在 Grid 栅格控件内部,以便与 Grid 控件配合使用。
- 水平调整列宽:若要允许 GridSplitter 控件水平调整左右列的宽度,则需要将 HorizontalAlignment 属性设置为 Stretch 或者 Center。
- 垂直调整行高:若要允许 GridSplitter 控件垂直调整行的高度,则需要将 VerticalAlignment 属性设置为 Stretch 或者 Center。
- ShowsPreview 属性:该属性表示拖动 GridSplitter 控件时是否即时绘制调整尺寸的预览效果。
代码示例:
XML
<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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="学习之路" Height="450" Width="800">
<Grid>
<!-- 使用 Grid 控件进行布局 -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<!-- 列之间的分隔符 -->
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- 左侧区域 -->
<Border Background="LightBlue" Grid.Column="0">
<TextBlock Text="左侧内部" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<!-- GridSplitter 控件 -->
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowsPreview="True"/>
<!-- 右侧区域 -->
<Border Background="LightGreen" Grid.Column="2">
<TextBlock Text="右侧内部" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</Window>
通过这种布局,用户可以通过拖动 GridSplitter 控件来调整左右两个区域的宽度,从而实现灵活的布局调整。