以下内容介绍 WPF 中 Binding 的核心概念、常用功能点、使用方式,并附文档链接。
一、Binding 概述
- 作用:将目标属性(DependencyProperty)与数据源属性建立连接,随数据变化自动更新 UI,或反向更新数据。
- 数据源查找:Binding.Source > Binding.ElementName > Binding.RelativeSource > DataContext(沿视觉树继承)。
- 典型能力:绑定模式、更新时机、路径语法、格式化与空值处理、转换器、相对/元素绑定、多值/优先级绑定、校验与诊断、异步绑定等。
二、常用功能点
- 绑定模式 Mode:OneWay、TwoWay、OneTime、OneWayToSource、Default。
- 更新时机 UpdateSourceTrigger:PropertyChanged、LostFocus、Explicit;可配合 Delay 节流文本输入。
- 路径 Path:支持子属性、索引器、附加属性路径。
- 格式与空值:StringFormat、TargetNullValue、FallbackValue。
- 转换器:Converter、ConverterParameter、ConverterCulture;多值用 MultiBinding+IMultiValueConverter 或 MultiBinding.StringFormat。
- 源定位:Source、ElementName、RelativeSource(AncestorType、TemplatedParent、Self 等)。
- 多值与优先级:MultiBinding、PriorityBinding。
- 校验与错误 UI:ValidatesOnDataErrors、ValidatesOnExceptions、ValidatesOnNotifyDataErrors、ValidationRules、BindingGroup。
- 诊断:diag:PresentationTraceSources.TraceLevel 输出绑定日志。
- 其他:IsAsync 异步获取、NotifyOnTargetUpdated/SourceUpdated 事件。
三、使用方式
- XAML:演示 TwoWay、格式化/空值、ElementName、RelativeSource、MultiBinding、PriorityBinding、可见性转换、诊断日志等
xml
<UserControl x:Class="H.Test.DataGrid.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
</UserControl.Resources>
<StackPanel Margin="12" Orientation="Vertical" Spacing="8">
<!-- TwoWay + UpdateSourceTrigger + Delay -->
<TextBox PlaceholderText="输入名(300ms 节流)"
Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Delay=300}"/>
<!-- StringFormat / TargetNullValue / FallbackValue -->
<TextBlock Text="{Binding Age, StringFormat=年龄:{0} 岁}"/>
<TextBlock Text="{Binding NonExist, TargetNullValue=空值替代, FallbackValue=绑定失败}"/>
<!-- 元素名绑定 ElementName -->
<Slider x:Name="S" Minimum="0" Maximum="100" Value="42"/>
<TextBlock Text="{Binding ElementName=S, Path=Value, StringFormat=滑块:{0:F0}}"/>
<!-- 相对源绑定 RelativeSource 到祖先 -->
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl},
Path=ActualWidth,
StringFormat=控件宽:{0:F0}}"/>
<!-- MultiBinding(字符串格式拼接多个源) -->
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="姓名:{0} {1}">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<!-- PriorityBinding:优先取第一个可用值 -->
<TextBlock>
<TextBlock.Text>
<PriorityBinding FallbackValue="无数据">
<Binding Path="DisplayName"/>
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
<!-- 转换器:布尔转可见性 -->
<TextBlock Text="正在处理..." Visibility="{Binding IsBusy, Converter={StaticResource BoolToVis}}"/>
<!-- 诊断:输出绑定日志到输出窗口 -->
<TextBlock Text="{Binding Missing, diag:PresentationTraceSources.TraceLevel=High}"/>
</StackPanel>
</UserControl>
- 代码后置:简单 ViewModel 与 DataContext(INotifyPropertyChanged)
csharp
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
namespace H.Test.DataGrid
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
DataContext = new PersonViewModel
{
FirstName = "Ada",
LastName = "Lovelace",
Age = 28,
IsBusy = true
};
}
}
public sealed class PersonViewModel : INotifyPropertyChanged
{
private string _firstName = "";
private string _lastName = "";
private int _age;
private bool _isBusy;
public string FirstName { get => _firstName; set { _firstName = value; OnPropertyChanged(); } }
public string LastName { get => _lastName; set { _lastName = value; OnPropertyChanged(); } }
public int Age { get => _age; set { _age = value; OnPropertyChanged(); } }
public bool IsBusy { get => _isBusy; set { _isBusy = value; OnPropertyChanged(); } }
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string? name = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
四、常见"坑"与建议
- 文本输入默认在 LostFocus 才回写源;实时回写请设 UpdateSourceTrigger=PropertyChanged,可配合 Delay 节流。
- FallbackValue 用于绑定失败(找不到源/路径),TargetNullValue 用于源值为 null。
- 多层 DataContext 可能被覆盖;相对源/元素名绑定可绕过 DataContext。
- Validation 与异常校验会阻止回写;注意抛异常的代价与用户体验。
- 大量绑定时,可用 Debug > Windows > Output 查看 diag 绑定日志。
五、文档链接
- Binding | Microsoft Learn
- BindingBase | Microsoft Learn
- RelativeSource | Microsoft Learn
- MultiBinding | Microsoft Learn
- PriorityBinding | Microsoft Learn
- IValueConverter | Microsoft Learn
- UpdateSourceTrigger | Microsoft Learn
- BindingOperations | Microsoft Learn
- BindingExpression | Microsoft Learn
- Validation(校验)| Microsoft Learn
- PresentationTraceSources | Microsoft Learn
了解更多
System.Windows.Controls 命名空间 | Microsoft Learn
控件库 - WPF .NET Framework | Microsoft Learn
使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn
HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频