C#之WPF学习之路(3)

目录

布局控件

布局控件概述

Panel基类

Grid控件(网格布局)

一、左右排列

二、上下排列

三、上下左右排列

四、跨列排列

五、固定列宽

六、调整行高和列宽

七、Grid显示网格线

总结

UniformGrid控件(均分布局)

StackPanel控件(栈式布局)

WrapPanel控件(瀑布流布局)

DockPanel控件(停靠布局)

VirtualizingStackPanel 类

Canvas控件(绝对布局)

Border控件(边框布局)

GridSplitter分割窗口


布局控件

布局控件概述

在C#中使用WPF(Windows Presentation Foundation)进行布局控件时,你可以利用XAML(Extensible Application Markup Language)和代码来创建灵活、响应式的用户界面。WPF提供了多种布局控件,可以帮助你轻松地管理和设计界面布局。

以下是一些常用的WPF布局控件以及它们的概述:

  • Grid(网格):网格控件允许你创建灵活的行和列布局,可以将控件按照网格中的行和列进行排列。
  • StackPanel(堆栈面板):堆栈面板控件允许你按照水平或垂直方向对控件进行堆叠排列,依次放置在同一个方向上。
  • WrapPanel(自动换行面板):自动换行面板控件类似于堆栈面板,但是在控件放置到一行后会自动换行,适用于需要动态添加并且自动换行的布局。
  • DockPanel(停靠面板):停靠面板控件允许你将子控件停靠在父容器的边缘,可以停靠在上、下、左、右或者中间。
  • UniformGrid(均匀网格):均匀网格控件类似于网格,但是所有单元格的大小都是相同的。
  • Canvas(画布):画布控件允许你使用绝对坐标进行子控件的定位,适用于需要精确布局的场景。
  • Border(边框):边框控件可以用于装饰其他控件,可以设置边框和背景颜色等属性。

这里面除了Border控件,其它控件都继承于Panel基类。

Panel基类

命名空间:

System.Windows.Controls

程序集:

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控件实现左右排列的简单示例:

<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>

二、上下排列

<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应该位于哪一行。

三、上下左右排列

<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>

四、跨列排列

<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>

五、固定列宽

<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控件将在界面上显示出网格线,方便布局调整和调试。

<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来实现。

代码示例:

<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,以实现更灵活的布局。

代码示例:

<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来实现自动换行布局:

<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时,最后一个未设置停靠位置的子元素不会填充剩余空间,而是根据自身大小进行布局。

<DockPanel LastChildFill="False" VerticalAlignment="Top">

设置LastChildFill="False"表示最后一个未设置停靠位置的子元素不会填充DockPanel的剩余空间。而VerticalAlignment="Top"则是将DockPanel在其父元素中垂直对齐到顶部。

下面是一个简单的示例,演示了如何使用DockPanel来实现停靠布局:

<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可以显著减少内存占用和提高界面的响应速度。

代码示例:

<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>
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 控件进行绝对布局:

<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 等画刷类型。

代码示例

<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 控件时是否即时绘制调整尺寸的预览效果。

代码示例:

<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 控件来调整左右两个区域的宽度,从而实现灵活的布局调整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/699418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录Day60 | 647. 回文子串 647. 回文子串

代码随想录Day60 | 647. 回文子串 647. 回文子串 647.回文子串516.最长回文子序列 647.回文子串 文档讲解&#xff1a;代码随想录 视频讲解&#xff1a; 动态规划&#xff0c;字符串性质决定了DP数组的定义 | LeetCode&#xff1a;647.回文子串 状态 dp数组 dp[i][j] 表示字符串…

c++逻辑值bool使用介绍

在 C 中&#xff0c;bool 是一种基本数据类型&#xff0c;用于表示逻辑值&#xff0c;取值为 true 或 false。bool 类型通常用于条件判断和逻辑运算&#xff0c;是 C 中非常重要的数据类型之一。 以下是关于 bool 类型的详细介绍&#xff1a; 定义和赋值&#xff1a; bool i…

Vue v-for、v-if、v-show常见问题

vue使用v-for遍历对象时&#xff0c;是按照什么顺序遍历的&#xff1f;如何保证顺序&#xff1f; 会先判断对象是否存在iterator接口&#xff0c;如果有循环执行next()方法。 没有iterator的情况下&#xff0c;会调用Object.Keys()方法&#xff0c;在不同的浏览器中&#xff…

Ansible-Tower web界面管理安装

Ansible-Tower web界面管理安装 Ansible-Tower 介绍 Ansible-Tower&#xff08;之前叫做awx&#xff09;是将ansible的指令界面化&#xff0c;简明直观&#xff0c;简单易用。Ansibke-tower其实就是一个图形化的任务调度&#xff0c;复杂服务部署&#xff0c;IT自动化的一个管…

有哪些适合程序员做的副业?

如果你经常玩知乎、看公众号&#xff08;软件、工具、互联网这几类的&#xff09;你就会发现&#xff0c;好多资源连接都变成了夸克网盘、迅雷网盘的资源链接。 例如&#xff1a;天涯神贴&#xff0c;基本上全是夸克、UC、迅雷网盘的资源链接。 有资源的前提下&#xff0c;迅雷…

pytorch建模的三种方式

# 可以使用以下3种方式构建模型&#xff1a; # # 1&#xff0c;继承nn.Module基类构建自定义模型。 # # 2&#xff0c;使用nn.Sequential按层顺序构建模型。 # # 3&#xff0c;继承nn.Module基类构建模型并辅助应用模型容器进行封装(nn.Sequential,nn.ModuleList,nn.ModuleDict…

泛微e-office系统敏感信息泄露漏洞

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 1、系统简介 泛微e-office系统是标准、易用、快速部署上线的专业协同OA软…

jackson、gson、fastjson和json-lib四种主流json解析框架对比

一、四种框架的介绍和对比 在Java中&#xff0c;Jackson、Gson、Fastjson和json-lib都是流行的JSON解析框架&#xff0c;它们各自有一些特点和优势。下面是对它们进行简要介绍和对比&#xff1a; 1.1 介绍 1&#xff09; Jackson: Jackson是由FasterXML开发的一个高性能的J…

01VScode开发stm32环境搭建

title: VScode开发stm32环境搭建 tags: STM32vscode 1.准备工作 1.下载并安装VSCODE 在百度上搜索vscode记住一定要是官方的 不然你自己就是在给自己下毒2345全来了 打红圈一定要有不然就是在垃圾网站上下的 VSCode下载链接 选一个适合你的      安装正常流程走就行不再…

Kafka生产常见问题分析与总结

Kafka生产常见问题分析与总结 消息丢失 生产者 acks 0 不需要等待任何Broker确认收到消息的回复就可以继续发消息 性能最高&#xff0c;但是最容易丢消息&#xff0c;对于数据丢失不敏感的场景可以使用&#xff0c;如大数据统计报表 acks 1 只要等待Broker中的leader成功写…

入侵检测系统的设计与实现

入侵检测系统&#xff08;Intrusion Detection System&#xff0c;简称IDS&#xff09;是一种能够监视网络或计算机系统活动的安全工具&#xff0c;旨在识别并响应可能的恶意行为或安全事件。这些事件可能包括未经授权的访问、恶意软件、拒绝服务攻击等。入侵检测系统通过不同的…

高并发Server的基石:reactor反应堆模式

业务开发同学只关心业务处理流程。但是我们开发的程序都是运行服务端server上&#xff0c;服务端server接收到IO请求后&#xff0c;是如何处理请求并最终进入业务流程的呢&#xff1f;这里不得不提到reactor反应堆模型。nginx tomcat redis nodejs dubbo等软件的网络处理模型都…

JS进阶——一些常用的字符串方法

charAt(index): 返回在指定位置的字符。 const str "Hello"; console.log(str.charAt(1)); // 输出 "e" concat(string2, string3, ..., stringX): 连接两个或更多字符串&#xff0c;并返回新的字符串。 const str1 "Hello"; const str2 …

SwiftUI 支持拖放功能的集合视图(Grid)如何捕获手指按下并抬起这一操作

功能需求 假设我们开发了一款 SwiftUI 应用,其中用户可以通过拖放 Grid 中的 Cell 来完成一些操作。现在,我们希望用户在某个 Cell 被按下并随后抬起手指时得到通知,这能够实现吗? 如上图所示,我们准确地捕获到了手指在 Grid 的 Cell 上按下再抬起这一操作!那么它是如何…

R语言【BIEN】——BIEN_occurrence_species():从BIEN中提取指定物种的观察数据

Package BIEN version 1.2.6 Description BIEN_occurrence_species()从BIEN数据库下载特定物种的观察记录。 Usage BIEN_occurrence_species(species,cultivated FALSE,new.world NULL,all.taxonomy FALSE,native.status FALSE,natives.only TRUE,observation.type FAL…

Linux之ACL访问控制列表

一、ACL权限的介绍 1.1 什么是ACL 访问控制列表&#xff08;ACL&#xff09;是一种网络安全技术&#xff0c;它通过在网络设备&#xff08;如路由器、交换机和防火墙&#xff09;上定义一系列规则&#xff0c;对进出接口的数据包进行控制。这些规则可以包含“允许”&…

123 Linux C++ 系统编程2 Linux 上安装卸载程序三种方法,linux 下解压缩命令 tar介绍。kill命令,top命令,umask 命令

一 通过命令和网络直接安装 sudo apt-get update sudo apt-get update 的工作就是将自己本地 ubutun的软件列表和 aliyun 的软件列表对比&#xff0c;如不一样&#xff0c;则更新。 sudo apt-get install 软件名 真正的安装 那么这里就有一个问题了&#xff0c; 怎么从aliy…

【初始RabbitMQ】死信队列的实现

死信的概念 死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c;consumer 从 queue 取出消息 进行消费&#xff0c;但某些时候由于特定的原因导致…

认识HarmonyOS

1.认识HarmonyOS 1.1.HarmonyOS简介 在中美贸易战的刺激下&#xff0c;国产操作系统HarmonyOS&#xff08;鸿蒙操作系统&#xff09;开始进入到大众的视野。 鸿蒙寓意为“万物起源”&#xff0c;发展至今已经经过了好几个迭代版本。 1.1.1.早期鸿蒙雏形 LiteOS 2015 年 5 月 …

STM32F103x 的时钟源

AHB (Advanced High-performance Bus) 高速总线&#xff0c;用来接高速外设的。 APB (Advanced Peripheral Bus) 低速总线&#xff0c;用来接低速外设的&#xff0c;包含APB1 和 APB2。 APB1&#xff1a;上面连接的是低速外设&#xff0c;包括电源接口、备份接口、 CAN 、 US…