WPF新手村教程(一)看不懂怎么办?别找我!
摘要:WPF个人文档(一)—— 基础语法&组件篇 前言 我简单讲两句 一句 两句 你不皮一下是不是就不开心啊 一、XAML基础语法 1.xaml语言简介 XAML 是一种声明性标记语言,应用于 .NET 编程模型时,XAM
WPF个人文档(一)—— 基础语法&组件篇
前言
我简单讲两句
一句
两句
你不皮一下是不是就不开心啊
一、XAML基础语法
1.xaml语言简介
XAML 是一种声明性标记语言,应用于 .NET 编程模型时,XAML 简化了为 .NET 应用创建 UI
以文本形式表示时,XAML 文件是通常具有扩展名的 .xaml 文件
可通过任何 XML 编码进行编码,但编码通常为UTF-8格式
2.对象(Object)元素
对象元素,通过声明 XML 元素来实例化 CLR 类或结构
XAML 例如 <Button>标签,其实是在说 "帮我创建一个 C# 类的对象"
用标签名当类名, <Button> 可以看作是 new Button()
而标签内部写的内容,实际上是在给对象设置属性
XAML 标签(对象元素)就是 C# 对象;标签属性就是 C# 属性;标签正文是内容属性
对象元素语法有两种:
1.自闭合 => 控件无内容
以左尖括号(<)开始,中间写属性,然后以正斜杠紧跟右尖括号结束(/>)
<Button Name="CheckoutButton"/>
2.成对标签 => 控件有内容
以<组件>开始,中间写内容属性,以</组件>结束
<TextBox>
我是 Text 内容属性
</TextBox>
看了微软官方的语法详讲,它叽里咕噜的在说什么呢
3.属性
语法:
<控件 属性名="属性值" />
<!-- —————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- 示例 -->
<Button Name="CheckoutButton"/>
别管微软官方文档那一堆叽里咕噜的话的,就这么简单
4.属性(Property)元素
属性元素以<控件.属性名>开始,</控件.属性名>结束,中间内容是属性值所对应类型的对象元素
语法示例:
<控件>
<控件.属性名>
<!-- 对象元素 -->
<属性类型 属性名="属性值"/>
</控件.属性名>
</控件>
<!-- —————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- 示例 -->
<Button>
<Button.Background>
<SolidColorBrush Color="Red"/>
</Button.Background>
<!-- Content => 这个内容属性指按钮里面放的东西,可以是文字,也可以是图片等-->
<Button.Content>
这是一个按钮
</Button.Content>
</Button>
5.集合
集合属性 = 如果类型是 IList/IDictionary/Array,子元素就是集合项
XAML 在加载时评估每项为对象并隐式调用 Add 来加入集合
如果要显式写集合对象,集合类必须有无参构造函数
显式集合语法:写出集合本身
隐式集合语法:不写集合,直接写集合的子项
别管什么隐式显式了,在多看一眼我就要大隐隐于市了(语文老师:这成语我是这样教你用的?)
语法:
<!-- 隐式集合 => 属性名被我吃了(不写集合对象本身,系统自动创建) -->
<控件>
<集合元素 /> <!-- 自动加入控件的某个集合属性 -->
<集合元素 />
</控件>
<!-- —————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- 示例 -->
<StackPanel>
<Button Content="按钮1" />
<Button Content="按钮2" />
</StackPanel>
<!-- 显式集合 => 明确写出属性名(写集合对象本身) -->
<控件>
<控件.集合属性名>
<集合类型> <!-- 显式写出集合对象本身 -->
<集合元素 />
<集合元素 />
</集合类型>
</控件.集合属性名>
</控件>
<!-- —————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- 示例 -->
<!-- Polyline => 用三个坐标点画一条折线 -->
<Polyline Stroke="Black" StrokeThickness="2">
<Polyline.Points>
<PointCollection>
<Point X="0" Y="0" />
<Point X="50" Y="20" />
<Point X="100" Y="0" />
</PointCollection>
</Polyline.Points>
</Polyline>
6.内容属性
内容属性 = "默认接收子元素或文本的属性"
内容属性只能有一个且内容必须是连续的(不能中间夹其他属性元素)
<!-- ✅ -->
<Button>
I am a blue button
</Button>
<!-- ❌ -->
<Button>
I am a
<Button.Background>
Blue
</Button.Background>
blue button
</Button>
示例:
<!--Border 的内容属性是 Child-->
<!-- 显式写法 -->
<Border>
<Border.Child>
<TextBox Width="300"/>
</Border.Child>
</Border>
<!-- 隐式写法 -->
<Border>
<TextBox Width="300"/>
</Border>
<!-- —————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- Button 的内容属性是 Content -->
<!-- 显式写法 -->
<Button>
<Button.Content>
点击我
</Button.Content>
</Button>
<!-- 隐式写法 -->
<Button>
点击我
</Button>
7.根元素 和 命名空间
根元素:XAML 文件中最外层的元素,就是整个 XAML 的根
XAML 文件必须有一个根元素,WPF中通常使用Window,Application,Page等作为根
根元素下面的元素都是根元素的子元素
需要特别注意:每个 XAML 文件有且只能有一个根元素
<!-- 这个XAML文件的根就是Window -->
<!-- Grid和Button都是根元素Window的子元素 -->
<Window x:Class="WPF_Test.MainWindow"
......
<Grid>
<Button Content="点击我"/>
</Grid>
</Window>
命名空间:用来告诉 XAML 解析器 元素对应哪个 CLR 类库(指明控件所属类库或项目)
根元素还包含属性xmlns,而xmlns命名空间的类型定义
需要注意的是:xmlns="......"中的内容并不是网址
而是由微软官方定义的看起来有一点像网址的命名空间标识符(Namespace URI)
代码示例:
# 表示默认使用的命名空间
# 将整个 WPF 客户端/框架 XAML 命名空间映射为默认值
xmlns="......"
# 表示命名空间 mc
# 表示将单独的 XAML 命名空间映射到 mc
xmlns:mc="......"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:WPF_Test"
# 前者表示系统自带的命名空间 -> 对比C语言 #include <stdio>
# 后者表示自定义命名空间 -> 对比C语言 #include "MyCode"
<Window x:Class="WPF_Test.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:Icon="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
xmlns:uc="clr-namespace:DataMonitoring.UserControls"
xmlns:local="clr-namespace:WPF_Test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Polyline Stroke="Black" StrokeThickness="2">
<Polyline.Points>
<PointCollection>
<Point X="100" Y="100" />
<Point X="50" Y="20" />
<Point X="100" Y="10" />
</PointCollection>
</Polyline.Points>
</Polyline>
</Grid>
</Window>
8.类型转换器(TypeConverter)
微软官方:它指出属性值必须由字符串设置,字符串转换为其他对象类型或基元值的基本处理方式基于String类型本身,以及特定类型的本机处理 请求中译中
一个类或机制,用来把 XAML 文本值 转换成 CLR 对象
当你在 XAML 中写一个属性值(通常是字符串),XAML 解析器需要把它转换成控件的属性类型
TypeConverter = XAML 的翻译器,把字符串翻译成实际对象
示例:
最常见的就是设置颜色或者边距
编译器可不知道你的什么Red,什么数字是什么意思
只有通过类型转换器,它才可以知道是什么意思
<Button Background="Red" Content="点我"/>
<Button Margin="10,5,10,5" Content="按钮"/>
省流:
类型转换器就是翻译器,把你在xaml文件中写的字符串翻译成对象
如果没有转换器,XAML 就不能直接把 "Red" 或 "10,5,10,5" 放进属性里
9.事件(Event)
C#中事件是什么样子的,那么WPF中的事件就是什么样子的,我想,应该也没有人会不看C#基础语法先来看WPF吧
事件 = 控件告诉你 "我被()了",你执行事件函数 XX
在XAML中通常用 Click = "事件函数名"表示
示例代码:当你点击了按钮,触发点击事件Button_Click
<Button Content="点我" Click="Button_Click"/>
// 如果在XAML文件中写了事件,C#代码中会自动生成对应事件函数,然后逻辑自己写
private void Button_Click(object sender, RoutedEventArgs e)
{
// 业务逻辑
}
10.标记扩展
标记扩展主要用于简化语法,以不同于一般将属性值作为文本字符串或字符串可转换值处理的方式来处理它
{标记扩展 ...}
<!-- 标记扩展 -->
<TextBlock Text="{Binding Age}" />
<!-- 如果没有标记扩展 -->
<TextBlock>
<TextBlock.Text>
<Binding Path="Age"/>
</TextBlock.Text>
</TextBlock>
标记扩展
用途
示例
{Binding ...}
绑定数据(数据绑定表达式)
Text="{Binding UserName}"
{StaticResource ...}
查找静态资源
Background="{StaticResource BlueBrush}"
{DynamicResource ...}
动态查找资源
Background="{DynamicResource ThemeColor}"
{x:Static ...}
引用常量或静态属性
Text="{x:Static local:Config.AppName}"
{x:Type ...}
获取 Type 类型
Tag="{x:Type Button}"
{TemplateBinding ...}
模板绑定(控件模板内部)
Text="{TemplateBinding Content}"
11.附加属性
附加属性:某个类定义的属性,可以被其他完全无关的控件来使用
给子控件加额外信息,让父控件来 读取 / 处理
<!-- Grid.Row和Grid.Column 都不是 Button 的属性 -->
<Grid>
<!-- Row代表行,Column代表列,这里指将按钮放在第1行第2列 -->
<Button Content="点我" Grid.Row="1" Grid.Column="2"/>
</Grid>
二、基础控件
这部分主要使用代码演示,文档?文档叽里咕噜不知道在说什么,拿头看,不如直接代码演示
1.窗口常用属性
(1)标题Title,高度Height,宽度Width
# Window表示当前窗口根元素,也可以理解为当前窗口就是Window
# Title -> 窗口标题(图标名)
# Height -> 高度
# Width -> 宽度
Title="MainWindow" Height="450" Width="800">
(2)窗口初始位置 WindowStartupLocation
# 窗口初始位置位于 屏幕中央
WindowStartupLocation="CenterScreen"
# 窗口初始位置位于 所有者(需要手动设置)中间位置
# 所有者:这个解释起来有点抽象,你可以理解为:
# 一个主窗口,你点击了一个按钮,跳出来一个新窗口
# 你将主窗口设置为了新窗口的所有者,那么新窗口初始位置就是主窗口的中间位置
WindowStartupLocation="CenterOwner"
# 窗口初始位置位于坐标(100, 300)位置处 -> 左上角为原点
WindowStartupLocation="Manual" Top="100" Left="300"
(3)窗口图标修改 —— Icon
1)先添加图片文件到项目目录下,再右击图片选择属性,在 "高级→生成操作中选择Resourse(资源)"
部分版本Resourse直接翻译为"资源"选项
2)在对应位置设置该图片为图标图片
# 这里使用的是相对文件路径
Icon="/Images/1.jpg"
(4)应用程序图标(.exe可执行文件图标)修改
1)右击项目,选择属性
2)选择 "应用程序 → 资源 → 图标和清单"
特别注意,图标只能是.ico文件
(5)整体代码示例:
<Window x:Class="WPF_Test.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:WPF_Test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
WindowStartupLocation="CenterScreen">
<Grid>
</Grid>
</Window>
(6)其他常用的一些窗口属性
属性
类型
作用
Title
string
窗口标题
Width / Height
double
窗口宽高
MinWidth / MinHeight
double
最小尺寸
MaxWidth / MaxHeight
double
最大尺寸
WindowStartupLocation
enum
窗口初次显示位置:Manual / CenterScreen / CenterOwner
ResizeMode
enum
是否可调整大小:CanResize / CanMinimize / NoResize
WindowStyle
enum
边框样式:SingleBorderWindow、None(无边框)等
Top / Left
double
窗口在屏幕的位置(Manual 模式下才生效)
WindowState
enum
普通、最大化、最小化:Normal / Maximized / Minimized
ShowInTaskbar
bool
是否显示在任务栏
Topmost
bool
窗口是否置顶(所有窗口的顶层)
Icon
ImageSource
窗口图标(支持相对路径)
Background
Brush
背景色
AllowsTransparency
bool
是否允许透明(WindowStyle=None 时常用)
Opacity
double
窗口透明度(0~1)
Owner
Window
设置当前窗口的拥有者,用于子窗口位置与模式对话框
Content
UIElement
Window 的内容(通常是 Grid 或其他布局控件)
2.Grid
Grid 是 WPF 最强大的布局控件
Grid用行和列把界面分成格子,然后把控件放进这些格子里面
你甚至可以在Grid控件里面放Grid
(1)行和列
行和列都是默认从0开始计数的
组件未声明行列,默认第0行第0列
<Grid>
<!-- 定义行 RowDefinitions -->
<!-- 这里有3行 -->
<Grid.RowDefinitions>
<RowDefinition Height="50" /> <!-- 🌱固定值 => 50px -->
<RowDefinition Height="*" /> <!-- 🌱按比例分配剩余空间 => 1/3 -->
<RowDefinition Height="2*" /> <!-- 占剩余空间的2/3 -->
</Grid.RowDefinitions>
<!-- 定义列 ColumnDefinitions -->
<!-- 这里有3列 -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" /> <!-- 固定值 100px -->
<ColumnDefinition Width="Auto" /> <!-- 🌱根据内容自动 -->
<ColumnDefinition Width="*" /> <!-- 占全部剩余空间 -->
</Grid.ColumnDefinitions>
<Button Content="我不是按钮"/> <!-- 🌱默认第0行0列 -->
<Button Content="我是按钮"/> <!-- 🌱依旧默认第0行0列 -->
<Button Content="AAA" Grid.Row="1" Grid.Column="1"/> <!-- 🌱第1行1列 -->
</Grid>
(2)边框
ShowGridLines,bool类型,默认为False
<Grid ShowGridLines="True">
</Grid>
(3)合并行、列
Grid.RowSpan:合并行(部分资料翻译为:跨行,指单元格可以跨行进行多行操作)
Grid.ColumnSpan:跨列合并列(部分资料翻译为:跨列,指单元格可以跨列进行多列操作)
示例代码:
<!-- 将前2行和前3列合并到一个单元格中 -->
<Button Content="我不是按钮" Grid.ColumnSpan="2" Grid.RowSpan="3"/>
(4)分割布局 GridSplitter
GridSplitter:使用分隔线用于分割布局
代码示例:
在一个Grid布局中创建3列,第1列和第3列作为内容列,第二列作为分割线
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<!-- 分隔线 -->
<!-- ShowsPreview => 拖动分隔线时,是否出现预览状态,默认False -->
<GridSplitter ShowsPreview="True" Grid.Column="1" HorizontalAlignment="Center" Width="5"/>
<!-- TextBlock => 文本框; TextWrapping="Wrap" => 表示文本内容可自动换行 -->
<TextBlock Text="我是第一行" FontSize="20" TextWrapping="Wrap" Grid.Column="0"/>
<TextBlock Text="别听它的鬼话" FontSize="20" TextWrapping="Wrap" Grid.Column="2"/>
</Grid>
3.StackPanel
StackPanel = 堆叠布局容器
把子控件按照 水平 或 垂直 顺序,一个接一个摆放
1.默认 垂直布局 Vertical
2.可以定义高度和宽度
示例代码:
<Grid>
<!-- 默认垂直布局 => Orientation="Vertical" -->
<!-- 水平布局 => Orientation="Horizontal" -->
<StackPanel Orientation="Horizontal">
<Button Content="按钮A"/>
<Button Content="阿牛"/>
<TextBlock Text="AAA" TextWrapping="Wrap"/>
</StackPanel>
</Grid>
4.控件外边距Margin
Margin = 控件外边距
外边距:控件与"外部其他东西"之间的空隙
代码示例:
# 表示 上下左右 外边距均为100
# 🌱Margin="上下左右"
Margin="100"
# 表示 左、右外边距均为22 - 上、下外边距为33
# 🌱Margin="左右 上下"
Margin="22 33"
# 表示 左外边距为22 上外边距为33 右外边距均为22 下外边距为33
# 🌱Margin="左 上 右 下"
Margin="22 66 99 33"
<Grid>
<StackPanel Orientation="Vertical">
<Button Content="按钮A"/>
<!-- Margin的4个数值对应的是左/上/右/下 外边距(顺时针) -->
<Button Content="阿牛" Margin="10 10 10 10"/>
<TextBlock Text="AAA" TextWrapping="Wrap"/>
</StackPanel>
</Grid>
5.Border
Border:翻译过来是边界的意思,但是我更喜欢叫这个东西为 壳
Border = 给一个内容包上一层 边框 + 背景 的容器控件
盒子的外壳 → Border
盒子里面装的东西 → Child(内容属性)
[!IMPORTANT]
🌱特别注意:
Border中只能有一个控件,
但是你可以添加面板控件(StackPanel / Grid / DockPanel),在其中存放多个控件
间接实现Border拥有多个控件
Border
└── StackPanel (作为 Border 的唯一 Child)
├── TextBlock
├── Button
└── Image
(1)Border 的常用属性
属性
作用
示例
BorderBrush
边框颜色
BorderBrush="Black"
BorderThickness
边框粗细
BorderThickness="2"
Background
背景色
Background="LightGray"
CornerRadius
圆角
CornerRadius="10"
Padding
内边距
Padding="10"
代码示例:
<Grid>
<StackPanel Orientation="Vertical">
<Border BorderBrush="LightSteelBlue"
BorderThickness="2"
CornerRadius="15"
Padding="8">
<Button Content="这是一个有圆角的按钮" />
</Border>
<Button Content="阿牛" Margin="10 10 10 10" />
<Border BorderBrush="Black"
BorderThickness="1"
Background="LightYellow"
Padding="10">
<TextBlock Text="这是一个有边框的文本" />
</Border>
</StackPanel>
</Grid>
(2)使用Border绘画分隔线
<Window x:Class="WPF_Test.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:WPF_Test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
WindowStartupLocation="CenterScreen"
Icon="/Images/1.jpg">
<Grid ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- 横竖两条分隔线 -->
<Border Grid.RowSpan="3" Grid.Column="1" BorderBrush="Coral" BorderThickness="1 0 0 0"/>
<Border Grid.Row="2" Grid.ColumnSpan="3" BorderBrush="Coral" BorderThickness="0 1 0 0"/>
</Grid>
</Window>
6.WrapPanel
WrapPanel:子元素按水平或垂直方向排成一行(或一列),放不下就自动换行
是一种流式布局
默认水平布局 Horizontal
代码示例:
<!-- 水平布局 => Orientation="Horizontal" -->
<!-- 垂直布局 => Orientation="Vertical" -->
<WrapPanel Orientation="Vertical">
<Button Width="80" Height="30" Content="A"/>
<Button Width="80" Height="30" Content="B"/>
<Button Width="80" Height="30" Content="C"/>
<Button Width="80" Height="30" Content="D"/>
<Button Width="80" Height="30" Content="E"/>
<!-- 感觉太紧凑了可以使用Margin,例如Margin="5" -->
</WrapPanel>
效果示例:
7.DockPanel
DockPanel:控件贴边,最后一个占满剩余空间
是一种框架布局,常用于主界面框架(顶部栏、侧边栏等)
其他控件可以通过附加属性自定义布局,最后一个控件占满余下空间(你也可以设置不占满)
示例代码:
<!-- 最后一个控件是否自动占满剩余空间 => LastChildFill="True" -->
<DockPanel LastChildFill="True">
<!-- 设置控件位置 => DockPanel.Dock -->
<Button Content="看不见我看不见我" DockPanel.Dock="Top" Height="30"/>
<Button Content="我抓到你啦!" DockPanel.Dock="Bottom" Height="20"/>
<Button Content="蜜雪冰城" DockPanel.Dock="Left" Width="150"/>
<!-- 感觉不好看也可以加个边距,例如Margin="5" -->
<Button Width="20">
<TextBlock Text="正新鸡排" TextWrapping="Wrap"/>
</Button>
<Button Content="瑞星咖啡(自动填充)" DockPanel.Dock="Right"/>
</DockPanel>
效果示例:
8.均分布局 UniformGrid
UniformGrid = 平均切块的 Grid
所有子元素的大小完全一致,且自动按照 行 / 列均匀分布
核心属性:
Rows:指定一共几行
Columns:指定一共有几列
代码示例:
<!-- FirstColumn => 第一个元素要从第几列开始放 -->
<!-- UniformGrid一共定义了3行3列 -->
<UniformGrid FirstColumn="1" Rows="3" Columns="3">
<Button Content="111" Margin="2"/>
<Button Content="222" Margin="2"/>
<Button Content="333" Margin="2"/>
<Button Content="444" Margin="2"/>
</UniformGrid>
效果示例:
9.Canvas
Canvas:WPF中最自由的布局,通过绝对坐标定位子控件的布局容器 对于做过QT的来说,那熟悉的感觉来了
Canvas = 绝对定位的画布
附加属性:
但是基本上只使用Canvas.Left和Canvas.Top这两个属性
附加属性
说明
Canvas.Left
距离画布左边的距离
Canvas.Top
距离画布上边的距离
Canvas.Right
距离画布右边的距离
Canvas.Bottom
距离画布下边的距离
代码示例:
<Canvas Background="LightSteelBlue">
<Button Content="按钮A" Canvas.Left="50" Canvas.Top="20"/>
<Button Content="按钮B" Canvas.Left="80" Canvas.Top="50"/>
</Canvas>
效果演示:
10.WPF部分常用布局属性
属性名
适用控件
功能说明
示例
Width / Height
所有控件
宽高(固定值)
Width="200"
MinWidth / MinHeight
所有控件
最小尺寸
MinWidth="50"
MaxWidth / MaxHeight
所有控件
最大尺寸
MaxHeight="300"
Margin
所有控件
控件与外部的间距
Margin="10"
Padding
Border、Button、TextBox 等
内部内容与边框的距离
Padding="5"
HorizontalAlignment
所有控件
水平对齐方式:Left, Center, Right, Stretch
HorizontalAlignment="Center"
VerticalAlignment
所有控件
垂直对齐方式:Top, Center, Bottom, Stretch
VerticalAlignment="Bottom"
Row / Column(附加属性)
Grid 子控件
选择控件所在的行列
Grid.Row="1"
RowSpan / ColumnSpan
Grid 子控件
跨行/跨列
Grid.ColumnSpan="2"
Canvas.Left、Canvas.Top
Canvas 子控件
绝对坐标定位
Canvas.Left="50"
Canvas.Right、Canvas.Bottom
Canvas 子控件
相对右/下定位
Canvas.Right="10"
随笔参考:
1.XAML 语言概述 - WPF | Microsoft Learn
2.【第一阶段 WPF入门到进阶】WPF基础_哔哩哔哩_bilibili
最近公司没什么事情,整天只能看看语法,看看WPF,然后看了这么久,感觉再看下去人要看傻了,
于是乎,就开始写技术文档,然后再写下去,人要写傻了.......
活多的时候,疯狂祈求能不能早点下班啊,能不能放个双休假啊(¬_¬ )
没活的时候,疯狂祈求,能不能有个活干啊>︿<
