WPF教程
基础界面解释
<Window x:Class="WpfApp1.MainWindow"
<!--引入一组名称空间-->
<!--控件&&布局相关-->
<!--默认的名称空间,无需再取名字-->
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
<!--编译器相关,其中"x"就是映射过来的"名称空间"-->
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"
<!--Window对象的属性-->
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
- 解释说明
- 把Window,Grid当成对象
- 既然是对象,就有属性和字段来描述它
WPF绘制的形式
- 使用
Key和Value的形式
<Grid>
<!--绘制矩形-->
<!--<Rectangle Height="80" Width="200" Stroke="Black" Fill="Blue" />-->
<!--绘制三角形-->
<!--<Path Data="M 0,0 L 200,100 L 100,200 Z" Stroke="Black" Fill="Red"/>-->
</Grid>
- 实例演示:
WPF中使用自定义类作为资源的基本用法
// MainWindow.xaml
<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"
<!--引入主窗体的代码逻辑的名称空间,映射并命名为"local"-->
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" WindowStartupLocation="CenterScreen">
<Window.Resources>
<!-- 在窗口级资源字典中创建Human实例 -->
<local:Human x:Key="human" Name="Tim" />
</Window.Resources>
<Grid>
<!--绘制按钮并绑定点击事件-->
<Button Content="Show!!!" Width="120" Height="80" Click="ButtonClick" />
</Grid>
</Window>
// MainWindow.xaml.cs
using System.ComponentModel;
using System.Globalization;
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
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// 按钮的点击事件
private void ButtonClick(object sender, RoutedEventArgs e)
{
// 通过FindResource方法查找资源,并强制转换成 Human类型
Human h = this.FindResource("human") as Human;
if (h != null) {
MessageBox.Show(h.Name);
}
}
}
public class Human
{
// 声明两个属性
public String Name { get; set; }
public Human Child { get; set; }
}
}
- 该实例进阶: 如果新增
Child属性,值为字符串,如何让程序把该值自动识别为Name值呢,代码逻辑如下
<Window x:Class="WpfApp1.MainWindow"
......>
<Window.Resources>
<!-- 新增Child属性的字符串赋值 -->
<local:Human x:Key="human" Name="Tim" Child="Little Tim" />
</Window.Resources>
<Grid>
......
</Grid>
</Window>
using System.ComponentModel;
using System.Globalization;
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
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
Human h = this.FindResource("human") as Human;
if (h != null) {
// MessageBox.Show(h.Name);
MessageBox.Show(h.Child.Name);
}
}
}
// "特性"
[TypeConverterAttribute(typeof(NameToHumanTypeConverter))]
public class Human
{
public String Name { get; set; }
public Human Child { get; set; }
}
// 类型转换器实现
// TypeConverter作用: 实现XAML字符串到复杂类型的自动转换
public class NameToHumanTypeConverter : TypeConverter
{
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
string name = value.ToString(); // 获取XAML中的字符串值
Human child = new Human();
child.Name = name; // 赋值
return child;
}
}
}
WPF实例: 绘制一个带红色矩形按钮的窗口
<Window x:Class="WpfApp2.MainWindow"
......>
<Grid>
// <!--定义按钮-->
<Button Width="120" Height="60" >
<!--定义按钮的内容-->
<Button.Content>
<Rectangle Width="80" Height="20" Stroke="Black" Fill="Red" />
</Button.Content>
</Button>
</Grid>
</Window>
- 绘制
渐变色矩形实例,可以看出,代码很多
<Grid>
<Rectangle Width="200" Height="160" Stroke="Black">
<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="DarkBlue" />
<GradientStop Offset="1.0" Color="Blue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
- 优化实例如下
<Grid>
<Rectangle Width="200" Height="160" Stroke="Black">
<Rectangle.Fill>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.2" Color="LightBlue" />
<GradientStop Offset="0.7" Color="DarkBlue" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
- 在
XAML中为对象属性赋值
- Attribute=Value
- 属性标签
- 标签拓展
标签拓展实例
<Grid Margin="4">
<Grid.RowDefinitions>
<RowDefinition Height="24" /> <!-- 行0:高24px -->
<RowDefinition Height="4" /> <!-- 行1:间距4px -->
<RowDefinition Height="24" /> <!-- 行2:高24px -->
</Grid.RowDefinitions>
<!--文本框-->
<!--标签拓展-->
<TextBox x:Name="tb" Text="{Binding ElementName=sld,Path=Value}" />
<!--滑块-->
<Slider x:Name="sld" Grid.Row="2" Value="50" Maximum="100" Minimum="0" />
</Grid>
事件模型
- 关键对象解析
- 事件拥有者
- 事件
- 事件响应者
- 事件处理器
- 事件订阅(桥梁)
- 图片
点击事件实例
......
<Grid>
<Button Content="Click Me" Height="100" Width="200" Click="Button_Click" />
</Grid>
......
namespace WpfApp3
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
<!--点击事件相应-->
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello");
}
}
}
- 上面这个实例可以修改一下,变成下面这个样子
<Grid>
<!--Click="Button_Click"-->
<Button x:Name="button1" Content="Click Me" Height="100" Width="200" />
</Grid>
......
namespace WpfApp3
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// 利用委托,然后两次Tab键自动生成
this.button1.Click += Button1_Click;
// 这句也可以
// this.button1.Click += new RoutedEventHandler(Button1_Click);
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello");
}
}
}
- 现在
WPF的编程流行趋势,也可以像Vue一样,组件化编程,把一个个功能模块化,组件化,最终实现功能集 - 实例如下,先新建一个
WPF项目,然后再新建一个用户控件项目
<UserControl x:Class="WpfControlLibrary1.SalaryCalculator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="240" Height="160" Background="LightBlue">
<Canvas>
<Label Content="基本工资" Height="38" Canvas.Left="10" Canvas.Top="10" Width="85" Name="label1" />
<Label Content="岗位工资" Height="38" Canvas.Left="10" Canvas.Top="50" Width="85" Name="label2" />
<Label Content="实际工资" Height="38" Canvas.Left="10" Canvas.Top="90" Width="85" Name="label3" />
<TextBox Height="19" Canvas.Left="95" TextWrapping="Wrap" Text="TextBox" Canvas.Top="12" Width="121" Name="TextBox1" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<TextBox Height="19" Canvas.Left="95" TextWrapping="Wrap" Text="TextBox" Canvas.Top="53" Width="121" Name="TextBox2" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<TextBox Height="19" Canvas.Left="95" TextWrapping="Wrap" Text="TextBox" Canvas.Top="90" Width="121" Name="TextBox3" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<Button Content="计算" Height="22" Canvas.Left="95" Canvas.Top="128" Width="121" Name="Button1" Click="Button1_Click" />
</Canvas>
</UserControl>
namespace WpfControlLibrary1
{
public partial class SalaryCalculator : UserControl
{
public SalaryCalculator()
{
InitializeComponent();
}
// 响应点击事件
private void Button1_Click(object sender, RoutedEventArgs e)
{
this.TextBox3.Text = this.TextBox2.Text + this.TextBox1.Text;
}
}
}
主项目程序中先添加引用,引用该类库,然后调用组件
<Window x:Class="WpfApp4.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:WpfApp4"
mc:Ignorable="d"
<!--映射为controls-->
xmlns:controls="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--调用组件-->
<controls:SalaryCalculator Grid.Column="0" Grid.Row="0" />
<controls:SalaryCalculator Grid.Column="1" Grid.Row="0" />
<controls:SalaryCalculator Grid.Column="0" Grid.Row="1" />
<controls:SalaryCalculator Grid.Column="1" Grid.Row="1" />
</Grid>
</Window>

浙公网安备 33010602011771号