WPF-01概述

WPF 是 .NET 平台上的一个现代化 UI 框架,采用基于矢量的呈现引擎,旨在利用现代图形硬件,提供与分辨率无关的高质量用户界面。本文档基于官方概述,提炼 WPF 的核心功能,并通过图示和代码示例帮助读者快速上手。


一、WPF 是什么?

  • 定义:WPF 是一个用于构建 Windows 桌面应用程序的 UI 框架,它集成了 XAML、控件、数据绑定、布局、2D/3D 图形、动画、样式、模板、文档、媒体和文本排版等功能。
  • 两种实现
    • .NET 版本:开源,运行在 .NET 上(仅 Windows)。
    • .NET Framework 版本:作为 Windows 组件随 .NET Framework 分发。
  • 为何升级到 .NET:更好的性能、新的 API、语言改进、辅助功能增强、工具更新等。

二、WPF 编程模型

WPF 应用程序的编程体验类似于其他 .NET 框架(如 ASP.NET、Windows Forms):

  • 实例化类
  • 设置属性
  • 调用方法
  • 处理事件

此外,WPF 引入了两个增强特性:

  • 依赖属性:支持值继承、更改通知、节省内存。
  • 路由事件:支持隧道(预览)和冒泡两种传播方式。
标记与代码隐藏

WPF 将外观 (XAML 标记)与行为(代码隐藏)分离,类似于 ASP.NET 的 Web Forms。

xml 复制代码
<!-- MainWindow.xaml -->
<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Hello WPF" Height="200" Width="300">
    <StackPanel>
        <Button Name="btnClick" Click="BtnClick_Click">Click Me</Button>
        <TextBlock Name="txtMessage" Margin="5"/>
    </StackPanel>
</Window>
csharp 复制代码
// MainWindow.xaml.cs
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent(); // 合并标记与代码
    }

    private void BtnClick_Click(object sender, RoutedEventArgs e)
    {
        txtMessage.Text = $"Button clicked at {DateTime.Now}";
    }
}

关键点x:Class 指定代码隐藏类,InitializeComponent() 在构造函数中调用以加载 XAML 定义的 UI。


三、核心功能速览

1. 布局系统

WPF 布局基于相对定位两阶段协商(Measure 和 Arrange),提供灵活的布局控件:

布局控件 作用
Canvas 绝对定位,子控件指定坐标
DockPanel 子控件停靠到边缘
Grid 按行/列排列,类似表格
StackPanel 垂直或水平堆叠
WrapPanel 自动换行
VirtualizingStackPanel 支持虚拟化的堆叠

示例:DockPanel 布局

xml 复制代码
<DockPanel>
    <Button DockPanel.Dock="Top" Background="LightBlue">Top</Button>
    <Button DockPanel.Dock="Bottom" Background="LightGreen">Bottom</Button>
    <Button DockPanel.Dock="Left" Background="LightCoral">Left</Button>
    <Button Background="LightGray">Fill</Button>
</DockPanel>

附加属性DockPanel.Dock 是父控件提供给子控件的属性,用于指定停靠位置。

2. 数据绑定

数据绑定引擎自动在 UI 控件和数据源之间同步数据。绑定声明在 XAML 中完成:

xml 复制代码
<Window DataContext="{Binding MyPerson}">
    <StackPanel>
        <TextBlock Text="{Binding Name}" />
        <TextBox Text="{Binding Age, Mode=TwoWay}" />
    </StackPanel>
</Window>
  • 绑定源 :可以是任何 .NET 对象(需实现 INotifyPropertyChanged)。
  • 绑定目标:依赖属性。
  • 模式OneWayTwoWayOneTimeOneWayToSource

图示

复制代码
数据源 (Person)  ←→  绑定引擎  ←→  UI 控件
    Name = "张三"               TextBox.Text = "张三"
3. 控件

WPF 提供了丰富的内置控件,按功能分类:

  • 按钮ButtonRepeatButton
  • 数据显示DataGridListViewTreeView
  • 日期选择CalendarDatePicker
  • 对话框OpenFileDialogSaveFileDialog
  • 数字墨迹InkCanvasInkPresenter
  • 文档DocumentViewerFlowDocumentReader
  • 输入TextBoxRichTextBoxPasswordBox
  • 布局GridStackPanelDockPanel
  • 媒体ImageMediaElement
  • 菜单MenuContextMenuToolBar
  • 选择CheckBoxComboBoxListBoxRadioButtonSlider
  • 用户信息LabelProgressBarToolTip
4. 图形与动画

WPF 图形系统具有以下特点:

  • 与分辨率无关:基本单位是 1/96 英寸的"设备无关像素"。
  • 高精度:使用双精度浮点数。
  • 硬件加速:利用 GPU 减少 CPU 负载。

2D 图形:提供形状(Rectangle、Ellipse)、几何图形(Path)、画笔(SolidColorBrush、LinearGradientBrush)等。

xml 复制代码
<Rectangle Width="100" Height="50" Fill="Blue" RadiusX="10" RadiusY="10"/>
<Path Data="M 10,10 L 50,10 L 30,50 Z" Fill="Red" Stroke="Black"/>

3D 图形:可嵌入 3D 模型并与 2D 元素交互。

动画 :通过 StoryboardTimeline 实现属性动画。

xml 复制代码
<Button Content="Animate">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetProperty="Width"
                                     From="100" To="200" Duration="0:0:1"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>
5. 文本与排版

WPF 提供高质量的文本呈现:

  • 支持 OpenType 字体
  • ClearType 增强
  • 硬件加速文本渲染
  • 文本与图形、动画集成
xml 复制代码
<TextBlock FontFamily="Segoe UI" FontSize="24" FontWeight="Bold">
    Hello <Run Foreground="Red">WPF</Run>
</TextBlock>

四、自定义应用外观

1. 内容模型

不同控件支持不同的内容类型:

  • ContentControl :可包含单个任意对象(如 Button)。
  • HeaderedContentControl :包含内容和标题(如 GroupBox)。
  • ItemsControl :包含集合(如 ListBox)。
  • HeaderedItemsControl :包含标题和集合(如 TreeViewItem)。
xml 复制代码
<Button>
    <StackPanel Orientation="Horizontal">
        <Image Source="icon.png" Width="16" Height="16"/>
        <TextBlock Text="Click Me"/>
    </StackPanel>
</Button>
2. 样式

样式用于集中定义一组属性值,可应用于多个元素。

xml 复制代码
<Window.Resources>
    <Style TargetType="Button">
        <Setter Property="Background" Value="Orange"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Margin" Value="5"/>
    </Style>
</Window.Resources>
<Button>Styled Button</Button>
3. 模板
  • 控件模板:彻底改变控件外观,但保留行为。
  • 数据模板:定义数据对象的可视化方式。
xml 复制代码
<!-- 控件模板:圆形按钮 -->
<Button>
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Ellipse Fill="Green" Width="80" Height="80">
                <ContentPresenter HorizontalAlignment="Center"
                                  VerticalAlignment="Center"/>
            </Ellipse>
        </ControlTemplate>
    </Button.Template>
    Click
</Button>
xml 复制代码
<!-- 数据模板:自定义列表项外观 -->
<ListBox ItemsSource="{Binding Tasks}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsCompleted}"/>
                <TextBlock Text="{Binding Name}" Margin="5,0"/>
                <TextBlock Text="{Binding Priority}" Foreground="Gray"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
4. 资源

资源允许在应用程序范围内共享对象(画刷、样式、模板等),提高重用性和维护性。

xml 复制代码
<Window.Resources>
    <SolidColorBrush x:Key="GlobalBrush" Color="LightBlue"/>
    <Style TargetType="Button" x:Key="BtnStyle">
        <Setter Property="Background" Value="{StaticResource GlobalBrush}"/>
    </Style>
</Window.Resources>
<Button Style="{StaticResource BtnStyle}">Shared Style</Button>
5. 自定义控件

当现有控件无法满足需求时,可通过以下方式创建自定义控件:

基类 适用场景
UserControl 组合多个现有控件,快速创建可复用组件
Control 需要模板化外观和自定义行为,类似内置控件
FrameworkElement 需要自定义渲染逻辑(如绘图)

五、总结

WPF 通过声明式标记 (XAML)和代码隐藏 的分离,结合强大的依赖属性路由事件数据绑定样式与模板 ,为构建现代桌面应用提供了完整而灵活的解决方案。其硬件加速的图形系统与分辨率无关的布局,确保了应用在不同显示设备上的高质量呈现。无论是简单的业务系统,还是复杂的交互式设计工具,WPF 都能提供坚实的基础。

相关推荐
海盗12345 小时前
OxyPlot 在 WPF 中的使用
.net·wpf
晓纪同学8 小时前
WPF-04 XAML概述
wpf
△曉風殘月〆1 天前
如何在WPF中捕获窗口外的事件
wpf
爱吃烤鸡翅的酸菜鱼2 天前
Java 事件发布-订阅机制全解析:从原生实现到主流中间件
java·中间件·wpf·事件·发布订阅
武藤一雄3 天前
WPF中ViewModel之间的5种通讯方式
开发语言·前端·microsoft·c#·wpf
CSharp精选营3 天前
都是微软亲儿子,WPF凭啥干不掉WinForm?这3个场景说明白了
c#·wpf·跨平台·winform
baivfhpwxf20233 天前
wpf TextBlock 控件如何根据内容换行?
wpf
亘元有量-流量变现3 天前
鸿蒙、安卓、苹果音频设备技术深度解析与开发实践
android·wpf·harmonyos·亘元有量·积分墙
软泡芙3 天前
【Bug】ReactiveUI WPF绑定中依赖属性不更新的问题分析与解决方案
java·bug·wpf