【上位机——WPF】布局控件

布局控件

常用布局控件
Panel基类
Grid(网格)
UniformGrid(均匀分布)
StackPanel(堆积面板)
WrapPanel(换行面板)
DockerPanel(停靠面板)
Canvas(画布布局)
Border(边框)
GridSplitter(分割窗口)

常用布局控件

Grid:网格,根据自定义行和列来设置控件的布局
StackPanel:栈式面板,包含的元素在竖直或水平方向排成一条直线
WrapPanel:自动折行面板,包含的元素在排满一行后,自动换行
DockPanel:泊靠式面板,内部的元素可以选择泊靠方向
UniformGrid:网格,UniformGrid就是Grid的简化版,每个单元格的大小相同
Canvas:画布,内部元素根据像素为单位绝对坐标进行定位。
Border:装饰的控件,此控件用于绘制边框及背景,在Border中只能有一个子控件

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

Panel基类

所有Panel元素都支持FrameworkElement定义的基本大小调整和定位属性,包括Height、Width、HorizontalAlignment、VerticalAlignment、Margin和LayoutTransform。Panel公开对了解和使用布局至关重要的其他属性。Background属性用于借助Brush填充派生面板元素的边界之间的区域。Children表示组成Panel的子元素集合。InternalChildren表示Children集合的内容以及由数据绑定生成的成员。两者均由父Panel内承载的子元素的UIElementCollection组成。

Panel提供了附加属性,ZIndex。假如一个单行单列的Grid布局控件中有两个Button,正常情况下,这两个Button都会以撑满Grid中,那么到底哪一个Button在上面,哪一个在下面。就看这两个Button的Panel.ZIndex附加属性的值,值越大的在上面,而值较小的那个Button将被上面的Button遮盖,从而在视觉上,用户只能看到一个Button。

    <Grid Background="AliceBlue" PreviewMouseUp="Grid_PreviewMouseUp">
        <Button Panel.ZIndex="2" Content="按钮1" Width="200"  Height="30"/>
        <Button Panel.ZIndex="0" Content="按钮2" Width="200" Height="30"/>

    </Grid>

Grid(网格)

Grid控件是WPF中所有布局控件中最好用的一个,因为它是自适应屏幕的宽度,最关键的一点是,它在呈现时,其ActuaWidth实际宽度和ActualHeight实际高度会有一个计算值,我们在业务开发中,有时候要根据父控件的实际宽度和高度来计算子控件的呈现位置和大小。

<Window x:Class="WpfApp1.MyGrid"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="MyGrid" Height="450" Width="800">
    <!--展示线条-->
    <Grid ShowGridLines="True">
        
        <!--三行-->
        <Grid.RowDefinitions>
            <RowDefinition Height="*" /> <!--Height="100" 固定高度-->
            <RowDefinition Height="2*"/> <!--Height="2*" 等比例的高度-->
            <RowDefinition Height="2*"/> <!--Height="Auto" 跟随文本的高度-->
        </Grid.RowDefinitions>

        <!--两列-->
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/> <!--Width="Auto" 跟随文本的宽度-->
        </Grid.ColumnDefinitions>

        <!--第一行第一列-->
        <!--Grid.RowSpan="2" 合并单元格行-->
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.RowSpan="2" Text="文本1" Grid.Row="0" Grid.Column="0" FontSize="30"/>
        <!--第一行第二列-->
        <TextBlock Text="文本2" Grid.Row="0" Grid.Column="1" FontSize="30"/>

        <!--<TextBlock Text="文本3" Grid.Row="1" Grid.Column="0" FontSize="30"/>-->
        <TextBlock Text="文本4" Grid.Row="1" Grid.Column="1" FontSize="30"/>

        <!--Grid.ColumnSpan="2" 合并单元格列-->
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" 
                   Grid.ColumnSpan="2"
                   Text="文本5" Grid.Row="2" Grid.Column="0" FontSize="30"/>
        <!--<TextBlock Text="文本6" Grid.Row="2" Grid.Column="1" FontSize="30"/>-->


    </Grid>
</Window>

UniformGrid(均匀分布)

UniformGrid和Grid有些相似,只不过UniformGrid的每个单元格面积都是相等的,不管是横向的单元格或是纵向的单元格,它们会平分整个UniformGrid.

优势
简单性:UniformGrid的设计简单直观,易于理解和实现
均匀性:自动调整子元素的大小,使其在网格中均匀分布
灵活性:支持动态调整网格大小,适应不同屏幕尺寸和分辨率

UniformGrid提供了3个属性,分别是FirstColumn,Columns,Rows。
FirstColumn表示第一行要空几个单元格,Columns和Rows分别用于设置行数和列数。

<Window x:Class="WpfApp1.MyUniformGrid"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="均分布局" Height="450" Width="800">
        <!--三行三列 第一行空2个单元格-->
    <UniformGrid Rows="3" Columns="3" FirstColumn="2">
        <Button Content="xinyu1" Margin="10"/>
        <Button Content="xinyu2" Margin="10"/>
        <Button Content="xinyu3" Margin="10"/>
        <Button Content="xinyu4" Margin="10"/>
        <Button Content="xinyu5" Margin="10"/>
        <Button Content="xinyu6" Margin="10"/>
        <Button Content="xinyu7" Margin="10"/>
        <Button Content="xinyu8" Margin="10"/>
        <Button Content="xinyu9" Margin="10"/>
    </UniformGrid>
</Window>

StackPanel(堆积面板)

StackPanel用于水平或垂直堆叠子元素。也就是说StackPanel同样也有一个Children属性,而Children集合中的元素呈现在界面上时,只能是按水平或垂直方式布局。

<Window x:Class="WpfApp1.MyStackPanel"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="水平或垂直面板" Height="450" Width="800">
    <!--垂直排列 Orientation默认是垂直的-->
    <!--<StackPanel>
        <Button Content="Btn1"/>
        <Button Content="Btn2"/>
        <Button Content="Btn3"/>
        <Button Content="Btn4"/>
        <Button Content="Btn5"/>
    </StackPanel>-->
    
    <!--水平排列-->
    <StackPanel Orientation="Horizontal">
        <Button HorizontalAlignment="Center" Content="Btn1"/>
        <Button VerticalAlignment="Center" Content="Btn2"/>
        <Button Width="100" Content="Btn3"/>
        <Button Height="40" Content="Btn4"/>
        <Button Content="Btn5"/>
    </StackPanel>

    <!--<StackPanel Orientation="Vertical">
        --><!--Margin 外边距 左 上 右 下  Margin="10 15"  左右10 上下15--><!-- 
        <Button HorizontalAlignment="Center" Content="Btn1" Margin="10 15"/>
        <Button VerticalAlignment="Center" Content="Btn2"/>
        <Button Height="50" Content="Btn3"/>
        <Button Width="200" Content="Btn4"/>
        <Button Content="Btn5"/>
    </StackPanel>-->

</Window>

WrapPanel(换行面板)

WrapPanel控件表示将其子控件从左到右的顺序排列,如果第一行显示不了,则自动换至第二行,继续显示剩余的子控件。
只提供了3个属性
Orientation代表子控件的排列方向,默认是水平方向。
ItemWidth代表子控件最大宽度。
ItemHeight代表子控件最大高度。

<Window x:Class="WpfApp1.MyWrapPanel"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="换行面板" Height="450" Width="800">

    <!--Orientation默认是Horizontal-->
    <!--<WrapPanel>
        <TextBlock Text="xinyu1" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu2" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu3" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu4" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu5" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu6" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu7" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu8" FontSize="30" Margin="5"/>
        <TextBlock Text="xinyu9" FontSize="30" Margin="5"/>
    </WrapPanel>-->

    <!--<WrapPanel Orientation="Vertical">
        <TextBlock HorizontalAlignment="Center" Text="xinyu1"  Margin="5"/>
        <TextBlock HorizontalAlignment="Left" Text="xinyu2" Margin="5"/>
        <TextBlock HorizontalAlignment="Right" Text="xinyu3" Margin="5"/>
        <TextBlock Text="xinyu4" Margin="5"/>
        <TextBlock Text="xinyu5" Margin="5"/>
        <TextBlock Text="xinyu6" Margin="5"/>
        <TextBlock Text="xinyu7" Margin="5"/>
        <TextBlock Text="xinyu8" Margin="5"/>
        <TextBlock Text="xinyu9" Margin="5"/>
    </WrapPanel>-->

    <WrapPanel ItemHeight="110" ItemWidth="110" Orientation="Vertical">
        <Button HorizontalAlignment="Center" Content="xinyu1" Margin="5"/>
        <Button HorizontalAlignment="Left"  Content="xinyu2" Margin="5"/>
        <Button HorizontalAlignment="Right"  Content="xinyu3" Margin="5"/>
        <Button Content="xinyu4" Margin="5"/>
        <Button Content="xinyu5" Margin="5"/>
        <Button Content="xinyu6" Margin="5"/>
        <Button Content="xinyu7" Margin="5"/>
        <Button Content="xinyu8" Margin="5"/>
        <Button Content="xinyu9" Margin="5"/>
    </WrapPanel>
</Window>

DockerPanel(停靠面板)

<Window x:Class="WpfApp1.MyDockerPanel"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="MyDockerPanel" Height="450" Width="800">

    <!--LastChildFill="False" 指定最后一个控件的填充行为 False 不填充 默认/True是填充-->
    <!--<DockPanel LastChildFill="False">

        <Button DockPanel.Dock="Top" Content="top"/>
        <Button DockPanel.Dock="Left" Content="left"/>
        <Button DockPanel.Dock="Right" Content="right"/>
        <Button DockPanel.Dock="Bottom" Content="bottom"/>
        <Button Content="center"/>

    </DockPanel>-->

    <DockPanel LastChildFill="False" HorizontalAlignment="Center">

        <Button DockPanel.Dock="Top" Content="top"/>
        <Button DockPanel.Dock="Left" Content="left"/>
        <Button DockPanel.Dock="Right" Content="right"/>
        <Button DockPanel.Dock="Bottom" Content="bottom"/>
        <Button Width="200" Content="center"/>

    </DockPanel>
</Window>

Canvas(画布布局)

一个Panel的呈现就是测量和排列子控件,然后在屏幕上绘制它们,所以在布局的过程中会经过一系列的计算,那么子控件越多,执行的计算次数就越多,则性能就会变差,如果不需要进行复杂的布局,则尽量少用复杂布局控件。如果能简单布局实现就尽量使用构造相对简单的布局,如Canvas、UniformGrid等。这种布局可带来更好的性能,如果有可能,我们应尽量避免调用UndateLayout方法,每当Panel内的子控件改变其位置时,布局系统就可能触发一个新的处理过程。

使用场景

图形绘制:Canvas提供了一个坐标系,可以使用线、矩形、圆形、多边形等基本形状绘制各种图形
动画效果:Canvas可以与WPF的动画功能结合使用。
游戏开发
用户界面设计:Canvas可以用于实现自定义的用户界面控件,如自定义按钮、图标等。
数据可视化:Canvas可以用于绘制各种图表,如折线图、柱状图,用于展示数据

Canvas提供了4个依赖属性

LeftProperty
RightProperty
TopProperty
BottomProperty

Canvas是最基本的面板,只是一个存储控件的容器,它不会自动调整内部元素的排列及大小,它仅支持用显示坐标定位控件,它也允许指定相对任何角的坐标,而不仅仅是左上角。可以使用Left、Top、Right、Bottom附加属性在Canvas中定位控件。

<Window x:Class="WpfApp1.MyCanvas"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="画布布局" Height="450" Width="800">
    <Canvas>
        <Button Canvas.Right="0" Content="Btn1" Width="200" Height="40"/>
        <Button Canvas.Top="40" Content="Btn2" Width="200" Height="40"/>
        <Button Canvas.Left="200" Content="Btn3" Width="200" Height="40"/>
        <Button Canvas.Bottom="0" Content="Btn4" Width="200" Height="40"/>
        <Button Canvas.Left="300" Canvas.Bottom="100" Content="Btn5" Width="200" Height="40"/>
    </Canvas>
</Window>

Border(边框)

在另一个元素四周绘制边框和背景
继承FrameworkElement->Decorator->Border
Border只能有一个子级,若要显示多个子元素,需要在父Border内放置一个附加Panel元素,然后,可以在该Panel元素还总放置子元素。

属性:

BorderThickness:设置Border边框的厚度
Padding:设置子元素相对于Border边框的距离
CornerRadius:设置Border的圆角
BorderBrush:设置Border边框的颜色画刷
Background:设置Border的背景颜色画刷

<Window x:Class="WpfApp1.MyBorder"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="MyBorder" Height="450" Width="800">
    <Canvas>
        <!--BorderThickness="0 0 1 1" 左 上 右 下-->
        <Border Canvas.Left="20" Canvas.Top="20" BorderThickness="1" Width="100" Height="40" BorderBrush="Red">
            <TextBlock Text="矩形" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        </Border>
        
        <Border Canvas.Left="20" Canvas.Top="80" 
                CornerRadius="10" Background="Coral" 
                BorderThickness="1" Width="100" Height="40" BorderBrush="Blue">

            <TextBlock Text="圆角" VerticalAlignment="Center"
                       Foreground="White" HorizontalAlignment="Center"/>
        </Border>


        <Border Canvas.Left="20" Canvas.Top="160" 
                CornerRadius="100" Background="Gold" 
                BorderThickness="1" Width="200" Height="200">

            <TextBlock Text="圆型" VerticalAlignment="Center"
                       Foreground="Red" FontSize="60" HorizontalAlignment="Center"/>
        </Border>

    </Canvas>
</Window>

GridSplitter(分割窗口)

GridSplitter控件用来分割窗体的布局,必须放在Grid栅格控件中配合使用,通过鼠标按住GridSplitter进行左右或上下拖动,即可调整行列尺寸。

Note

如果希望GridSplitter控件可以水平调整左右的Grid列宽时,那么HorizontalAlignment属性必须设置为Stretch或者Center。
如果希望GridSplitter控件可以垂直调整行高,那么VerticalAlignment属性必须设置为Stretch或者Center
ShowsPreview当设置为true时,将显示行或列大小的更改预览,释放时GridSplitter的实际大小会发生变化。如果属性设置为false,则当用户拖动GridSplitter控件时,列或行大小将实时更新

<Window x:Class="WpfApp1.MyGridSplitter"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="MyGridSplitter" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Border Background="Green">
            <TextBlock Foreground="White" FontSize="20" TextWrapping="Wrap">
            1111111111111111111111111111111111111111111111111111111111111111111111</TextBlock>
        </Border>

        <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" ShowsPreview="True" />

        <Border Grid.Column="2" Background="Red">
            <TextBlock Foreground="White" FontSize="20" TextWrapping="Wrap">
            1111111111111111111111111111111111111111111111111111111111111111111111</TextBlock>
        </Border>
    </Grid>
</Window>
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容