WPF基本结构

1. WPF项目目录结构

框架使用NET 8.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PS E:\PersonalCSharpProject\WPFLearning\WpfApp1> tree /F
卷 WorkDisc 的文件夹 PATH 列表
卷序列号为 507E-08F0
E:.
│ global.json
│ WpfApp1.sln

└─WpfApp1
│ App.xaml
│ App.xaml.cs
│ AssemblyInfo.cs
│ MainWindow.xaml
│ MainWindow.xaml.cs
│ WpfApp1.csproj
│ WpfApp1.csproj.user

App.xaml是程序的入口文件,StartupUri="MainWindow.xaml"配置程序的主窗体。

MainWindow.xaml是主窗体的样式。

1
2
3
4
5
6
7
8
9
10
11
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"引入关于绘图的链接库,如Window标签,Grid标签。

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"引入关于xaml编译、解析相关的链接库。

xmlns:local="clr-namespace:WpfApp1"引用本地命名空间。

MainWindow.xaml.cs是主窗体的C#代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

MainWindow.xamlMainWindow.xaml.cs是一个类,也就是MainWindow类,因为partial关键字,可以将一个类分开定义,编译完成后合并在一起。InitializeComponent();方法由MainWindow.xaml.cs文件编译生成。

2. 在XAML中为对象赋值

XAML中,每个标签都是一个对象,标签里的键值对,其实就是属性。

2.1 Attribute=Value

键值对赋值方式适合简单操作

MainWindow.xaml.cs部分代码,NameToHumanTypeConventer用于转换Child="LittleTim"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[TypeConverter(typeof(NameToHumanTypeConventer))]
public class Human
{
public string Name { get; set; }
public Human Child { get; set; }
}

public class NameToHumanTypeConventer : TypeConverter
{
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
string name = value.ToString();
Human human = new Human() { Name = name };
return human;
}
}

MainWindow.xaml部分代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
<Window.Resources>
<local:Human
x:Key="Human"
Name="Tim"
Child="LittleTim" />
</Window.Resources>
<Grid>
<Button
Width="200"
Height="70"
Click="Button_Click"
Content="测试" />
</Grid>

点击事件

1
2
3
4
5
6
7
8
private void Button_Click(object sender, RoutedEventArgs e)
{
Human? human = this.FindName("Human") as Human;
if (human != null)
{
MessageBox.Show(human.Child.Name);
}
}

2.2 属性标签

主要结构为:<对象名.属性>,单独属性也可以,但是如果由同名的类就容易编译失败,最好加上对象名。下边绘制了一个渐变色矩形。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<Rectangle
Grid.Row="1"
Grid.Column="0"
Width="200"
Height="100">
<Rectangle.Fill>
<LinearGradientBrush>
<LinearGradientBrush.StartPoint>
<Point X="0" Y="0" />
</LinearGradientBrush.StartPoint>
<LinearGradientBrush.EndPoint>
<Point X="1" Y="1" />
</LinearGradientBrush.EndPoint>
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.2" Color="LightBlue" />
<GradientStop Offset="0.7" Color="Blue" />
<GradientStop Offset="1.0" Color="DarkBlue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>

结构优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Rectangle
Grid.Row="1"
Grid.Column="0"
Width="200"
Height="100">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.2" Color="LightBlue" />
<GradientStop Offset="0.7" Color="Blue" />
<GradientStop Offset="1.0" Color="DarkBlue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>

2.3 标签扩展

需要引入命名空间xmlns:sys="clr-namespace:System;assembly=netstandard"

1
2
3
<Window.Resources>
<sys:String x:Key="stringHello">Hello WPF!</sys:String>
</Window.Resources>
1
2
3
4
5
6
7
<TextBlock
Grid.Row="1"
Grid.Column="1"
Width="120"
Height="24"
Background="LightBlue"
Text="{StaticResource ResourceKey=stringHello}" />

3. WPF布局控件

3.1 Grid布局(网格布局)

Auto自适应高度

*倍率

{value}固定高度

Grid.ColumnSpan占据两列

Grid.RowSpam占据两行

3.2 StackPanel(堆栈面板布局)

orientation布局方向,水平布局参数Horizontal,垂直布局参数Vertical(默认)

相比于瀑布面板,不会自动换行

3.3 WrapPanel(瀑布面板布局)

3.4 DockPanel(停靠面板布局)

LastChildFill容器中的最后一个元素时, 默认该元素填充DockPanel所有空间, 默认值为True

包含在DockPanel中的元素, 具备DockPanel.Dock的4个枚举值 (Top/Left/Right/Bottom) 用于设置元素的锚定位置

3.5 UniformGrid

作者

神明大人

发布于

2025-02-18

更新于

2025-03-09

许可协议