《C#编程入门》 25-WPF初识

WPF六种布局元素

  • grid 网格
  • Canvas 画布
  • StackPanel 栈面板
  • WrapPanel 环绕面板
  • DockPanel 停靠面板
  • UniformGrid 均布网格

1、 Canvas布局

Canvas是一个类似于坐标系的面板,所有的元素通过设置坐标来决定其在坐标系中的位置。具体表现为使用Left、Top、Right、 Bottom附加属性在Canvas中定位控件。

<Window x:Class="WPF_Layout.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF-Layout" Height="350" Width="525">
<Grid>
<Canvas>
<Button Canvas.Left="50" Canvas.Top="50" Content="Button 1"></Button>
<Button Canvas.Right="50" Canvas.Top="50" Content="Button 2"></Button>
<Button Canvas.Left="50" Canvas.Bottom="50" Content="Button 3"></Button>
<Button Canvas.Right="50" Canvas.Bottom="50" Content="Button 4"></Button>
</Canvas>
</Grid>
</Window>

注意:如果同时设置 Canvas.Left="50"Canvas.Right="50",则以Canvas.Left="50"为准。如果同时设置Canvas.Top="50" Canvas.Bottom="50",则以Canvas.Top ="50"为准。(别这么丧心病狂地同时写Left和Right,请遵循基本的编程逻辑)

2 、StackPanel布局

StackPanel将控件按照行或列来顺序排列,但不会换行。通过设置面板的Orientation属性设置了两种排列方式:横排(Horizontal默认的)和竖排(Vertical),默认为竖排(Vertical)。

<Window x:Class="WPF_Layout.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF-Layout" Height="350" Width="525">
<Grid>
<StackPanel Name="stackpanel1" Orientation="Horizontal">
<Button Content="Button1"></Button>
<Button Content="Button2"></Button>
<Button Content="Button3"></Button>
</StackPanel>
<StackPanel Name="stackpanel2" Orientation="Vertical">
<Button Content="Button4"></Button>
<Button Content="Button5"></Button>
<Button Content="Button6"></Button>
</StackPanel>
<StackPanel Name="stackpanel3" Orientation="Horizontal" FlowDirection="RightToLeft">
<Button Content="Button7"></Button>
<Button Content="Button8"></Button>
<Button Content="Button9"></Button>
</StackPanel>
</Grid>
</Window>

注意:Orientation="Horizontal"时,设置FlowDirection属性为RightToLeft,,则元素将从右向左排列。

3、 DockPanel布局

DockPanel支持让元素简单地停靠在整个面板的某一条边上,然后拉伸元素以填满全部宽度或高度。它也支持让一个元素填充其他已停靠元素没有占用的剩余空间。
DockPanel有一个Dock附加属性,因此子元素用4个值来控制她们的停靠:Left、Top、Right、Bottom。Dock没有Fill值。作为替代,最后的子元素将加入一个DockPanel并填满所有剩余的空间,除非DockPanel的LastChildFill属性为false,它将朝某个方向停靠。

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <DockPanel>
            <Button Content="上" DockPanel.Dock="Left"></Button>
            <Button Content="下" DockPanel.Dock="Bottom"></Button>
            <Button Content="左" DockPanel.Dock="Left"></Button>
            <Button Content="右" DockPanel.Dock="Right"></Button>
        </DockPanel>
    </Grid>
</Window>

设置LastChildFill属性为false

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <DockPanel LastChildFill="False">
            <Button Content="上" DockPanel.Dock="Left"></Button>
            <Button Content="下" DockPanel.Dock="Bottom"></Button>
            <Button Content="左" DockPanel.Dock="Left"></Button>
            <Button Content="右" DockPanel.Dock="Right"></Button>
        </DockPanel>
    </Grid>
</Window>

4、 WrapPanel布局

WrapPanel布局面板将各个控件按照一定方向罗列,当长度或高度不够时自动调整进行换行换列。
Orientation="Horizontal"时各控件从左至右罗列,当面板长度不够时,子控件就会自动换行,继续按照从左至右的顺序排列。
Orientation="Vertical"时各控件从上至下罗列,当面板高度不够时,子控件就会自动换列,继续按照从上至下的顺序排列。

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <WrapPanel Orientation="Horizontal">
            <Button Content="Button 150" Width="150"></Button>
            <Button Content="Button 200" Width="200"></Button>
            <Button Content="Button 150" Width="150"></Button>
            <Button Content="Button 200" Width="200"></Button>
            <Button Content="Button 150" Width="150"></Button>
            <Button Content="Button 200" Width="200"></Button>
            <Button Content="Button 150" Width="150"></Button>
        </WrapPanel>
    </Grid>
</Window>

5、 Grid布局

Grid允许我们通过自定义行列来进行布局,这类似于表格.通过定义Grid的RowDifinitions和ColumnDifinitions来实现对于表格行和列的定义,元素根据附加属性Grid.Row和Grid.Column确定自己的位置。
1)Grid的列宽与行高可采用固定、自动、按比列三种方式定义
第一种,固定长度——值为一个确定的数字
第二种,自动长度——值为Auto,实际作用就是取实际控件所需的最小值
第三种,比例长度——表示占用剩余的全部宽度;两行都是,将平分剩余宽度;一个2,一个,则前者占剩余全部宽度的2/3,后者占1/3;依此类推

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="2*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Button 1"></Button>
        <Button Grid.Row="1" Content="Button 2"></Button>
        <Button Grid.Row="2" Content="Button 3"></Button>
        <Button Grid.Row="3" Content="Button 4"></Button>
    </Grid>
</Window>

2) 合并行或列

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="2*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Button 1"></Button>
        <Button Grid.Row="1" Content="Button 2"></Button>
        <Button Grid.Row="2" Grid.RowSpan="2" Content="Button 3"></Button>
    </Grid>
</Window>

3)GridSplitter重新分布Grid控件的列间距或行间距。(类似于WinForm中SplitContainer)

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="3"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Button"></Button>
        <GridSplitter Grid.Row="1" HorizontalAlignment="Stretch"></GridSplitter>
        <Button Grid.Row="2" Content="Button"></Button>
    </Grid>
</Window>

6、UniformGrid布局

UniformGrid就是Gird的简化版,每个单元格的大小相同,不需要定义行列集合。每个单元格始终具有相同的大小,每个单元格只能容纳一个控件。
若不设置RowsColums,则按照定义在其内部的元素个数,自动创建行列,并通常保持相同的行列数。若只设置Rows则固定行数,自动扩展列数。若只设置Colums则固定列数,自动扩展行数。
UniformGrid 中没有Row和Column附加属性,也没有空白单元格。

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <UniformGrid>
            <Button Content="Button"></Button>
            <Button Content="Button"></Button>
            <Button Content="Button"></Button>
            <Button Content="Button"></Button>
            <Button Content="Button"></Button>
            <Button Content="Button"></Button>
            <Button Content="Button"></Button>
        </UniformGrid>
    </Grid>
</Window>

7、ScrollViewer布局
ScrollViewer是带有滚动条的面板。在ScrollViewer中只能有一个子控件,若要显示多个子控件,需要将一个附加的 Panel控件放置在父 ScrollViewer中。然后可以将子控件放置在该控件中。
HorizontalScrollBarVisibility水平滚动条是否显示默认为Hidden
VerticalScrollBarVisibility垂直滚动条是否显示 默认为Visible。
一般我们都会设置 HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
意思是:当内容超出可视范围时,才显示横向/纵向滚动条

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <Button Content="Button" Width="800" Height="800"></Button>
        </ScrollViewer>
    </Grid>
</Window>

8、 ViewBox布局

Viewbox的作用是拉伸或延展位于其中的组件,以填满可用空间。在Viewbox中只能有一个子控件,若要显示多个子控件,需要将一个附加的Panel控件放置在父Viewbox中。然后可以将子控件放置在该控件中。
常用属性:
Stretch:获取或设置拉伸模式以决定该组件中的内容以怎样的形式填充该组件的已有空间。具体设置值如下:
None:不进行拉伸,按子元素设置的长宽显示。
Uniform:按原比例缩放子元素,使得一边不足,另一边恰好填充
Fill:缩放子元素,使得子元素的长变为Viewbox的长,宽变为Viewbox的宽
UniformToFill:按原比例缩放子元素,使得子元素一边恰好填充,另一边超出Viewbox的区域
Stretch默认值为Uniform。

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition>
                
            </RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition>
                
            </ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Viewbox Grid.Row="0" Grid.Column="0" Stretch="None">
            <Button Width="100" Height="50" Content="None"></Button>
        </Viewbox>
        <Viewbox Grid.Row="0" Grid.Column="1" Stretch="Uniform">
            <Button Width="100" Height="50" Content="Uniform"></Button>
        </Viewbox>
        <Viewbox Grid.Row="1" Grid.Column="0" Stretch="Fill">
            <Button Width="100" Height="50" Content="Fill"></Button>
        </Viewbox>
        <Viewbox Grid.Row="1" Grid.Column="1" Stretch="UniformToFill">
            <Button Width="100" Height="50" Content="UniformToFill"></Button>
        </Viewbox>
    </Grid>
</Window>

9、 Border

Border 是一个装饰的控件,此控件用于绘制边框及背景,在Border中只能有一个子控件,若要显示多个子控件,需要将一个附加的Panel控件放置在父Border中。然后可以将子控件放置在该 Panel控件中。
常用属性:
Background: 背景色 ;
BorderBrush: 边框色 ;
BorderThickness: 边框宽度;
CornerRadius: 各个角 圆的半径;

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Border Background="YellowGreen" BorderBrush="Black" BorderThickness="0, 2, 4, 6" CornerRadius="0, 10, 20, 30"></Border>
    </Grid>
</Window>

三 精确定位的常用属性
在设计UI时,WPF为我们提供了一些属性用于精确定位元素,其中最常用的有三个:Alignment(包括水平,垂直),Margin,Padding,具体用法如下:
HorizontalAlignment: 子元素在水平方向的对齐方式,有左对齐,右对齐,中间对齐,拉伸填充等四种方式。
VerticalAlignment:子元素在垂直方向的对齐方式,有顶端对齐,底部对齐,中间对齐,拉伸填充等四种方式。
Margin:用于指定元素与其父级或同级之间的距离,包括上下左右四个值。也可通过使用 Margin="20"同时指定四个值。
Padding:用于指定元素与其子级之间的距离,包括上下左右四个值。也可通过使用Padding="20"同时指定四个值。

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition>
                
            </RowDefinition>
            <RowDefinition>
                
            </RowDefinition>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Center" HorizontalAlignment="Center"></Button>
        <Button Grid.Row="1" Content="Left" HorizontalAlignment="Left"></Button>
        <Button Grid.Row="2" Content="Right" HorizontalAlignment="Right"></Button>
        <Button Grid.Row="3" Content="Stretch" HorizontalAlignment="Stretch"></Button>
    </Grid>
</Window>

<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Border Background="YellowGreen">
            <Button Margin="0, 50, 100, 150"></Button>
        </Border>
    </Grid>
</Window>
<Window x:Class="WPF_Layout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF-Layout" Height="350" Width="525">
    <Grid>
        <Border Background="YellowGreen" Padding="0, 50, 100, 150">
            <Button ></Button>
        </Border>
    </Grid>
</Window>
  1. 圆形头像
    在WPF上显示圆形图片很简单,使用Ellipse绘制圆形设置宽和高一致绘制正圆,在内部使用Image笔刷填充图片,本文中的头像显示方式均以此来实现。
<Ellipse Width="50"
             Height="50">
                <Ellipse.Fill>
                   <ImageBrush  ImageSource="Images/github.png" />
                </Ellipse.Fill>
</Ellipse>

第一个多边形

<Polygon Points="0,0 700,0 756,65 0,65"
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#1C93EC" />
                        </Polygon.Fill>
                    </Polygon>

第二个多边形

<Polygon Points="700,0 780,0 740,50 "
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#3E58C9" />
                        </Polygon.Fill>
                    </Polygon>

第三个多边形

<Polygon Points="780,0 1100,0 1100,65 723,65 "
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#3448A1" />
                        </Polygon.Fill>
                    </Polygon>

请关注我的公众号,简书号

![微信图片_20200503130052.jpg](https://upload-images.jianshu.io/upload_images/22838787-375f928f357cb02f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
微信图片_20200503130052.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358