Binding语法必须用{Binding …}包裹,支持属性路径和索引器但不支持方法调用;ViewModel需实现INotifyPropertyChanged且集合用ObservableCollection;常见错误包括属性名拼写错误、未触发通知、未设Mode=TwoWay或UpdateSourceTrigger不当。

Binding语法写法和基本结构
在XAML中使用MVVM模式做数据绑定,核心就是Binding标记扩展。它不是XML属性值的普通字符串,而是必须用{Binding ...}这种大括号包裹的语法,否则WPF/WinUI不会识别为绑定表达式。
最简形式是:{Binding}(绑定当前DataContext对象本身),常见写法是绑定属性名:{Binding UserName}、{Binding Items.Count}。
-
Path参数可省略,如{Binding UserName}等价于{Binding Path=UserName} - 路径支持点号导航(
Customer.Address.Street)和索引器(Items[0]) - 不能写方法调用或复杂表达式,比如
{Binding Name.ToUpper()}会直接报错 - 若绑定源不是
DataContext,需显式指定Source、RelativeSource或ElementName
Binding到ViewModel属性的前置条件
Binding能生效,不只靠XAML写对,更依赖ViewModel实现规范。WPF/WinUI默认只监听INotifyPropertyChanged通知,不自动响应字段或普通属性变更。
以下写法不会触发界面更新:
public string UserName = "Tom"; // 字段,无通知
public string UserName { get; set; } // 自动属性,无通知
正确写法必须手动触发通知:
private string _userName;
public string UserName
{
get => _userName;
set
{
_userName = value;
OnPropertyChanged(); // 或 RaisePropertyChanged("UserName")
}
}
- 推荐用
CommunityToolkit.Mvvm的[ObservableProperty]自动生成通知逻辑 -
ObservableCollection用于集合绑定,普通List增删项不会刷新界面 - 如果绑定的是静态资源(如
StaticResource定义的ViewModel),确保它在Resources中声明且已实例化
常见Binding错误及对应XML写法修正
运行时没报错但界面空白?多数是Binding失败被静默忽略。打开输出窗口看是否有System.Windows.Data Error日志。
典型错误现象和修复:
- “找不到属性‘XXX’” → 检查ViewModel类中是否存在
public属性XXX,拼写大小写必须完全一致 - 绑定显示为空字符串或0 → 属性初始值为
null/default,且未触发OnPropertyChanged -
{Binding ElementName=txtInput, Path=Text.Length}报错 →Path不支持链式调用方法,只能是属性或索引器 - ComboBox内容不更新 → 忘记设置
ItemsSource="{Binding Items}",只写了SelectedItem绑定
调试技巧:临时加NotifyOnSourceUpdated=True和UpdateSourceTrigger=PropertyChanged辅助定位方向。
Binding方向与UpdateSourceTrigger的实际影响
默认Mode=OneWay(ViewModel→View),但像TextBox.Text这类输入控件常需双向同步,必须显式设Mode=TwoWay,否则用户输入不会回写到ViewModel。
UpdateSourceTrigger决定何时把View修改提交回源,关键取值:
-
LostFocus(默认):TextBox失去焦点才更新,适合表单校验场景 -
PropertyChanged:每次按键都触发,适合实时搜索,但注意性能(避免频繁计算) -
Explicit:必须手动调用BindingExpression.UpdateSource(),少见但可控性强
示例:
注意:TwoWay不等于自动启用PropertyChanged——两者独立控制,漏设任一都可能导致单向失灵。
真正容易被忽略的是:某些控件(如CheckBox.IsChecked)默认就是TwoWay,但TextBlock.Text永远是OneWay,不能强行改Mode生效。
