在Avalonia中,
INotifyPropertyChanged是MVVM数据绑定的基石——它不是“可选优化”,而是UI自动响应数据变化的必要机制。只要ViewModel里的属性变了,但UI没更新,八成是这个接口没正确触发。
核心用法:继承ObservableObject + 属性自动通知
现代Avalonia项目基本不用手写
INotifyPropertyChanged实现。推荐直接继承
CommunityToolkit.Mvvm提供的
ObservableObject基类,再配合源生成器特性,简洁又安全: 定义ViewModel时继承
ObservableObject:
public partial class MainWindowViewModel : ObservableObject用
[ObservableProperty]标记字段(需启用源生成器):
[ObservableProperty] private string _title = "默认标题";
编译时自动生成
Title属性,含
set中自动调用
OnPropertyChanged手动触发通知(少数场景):
调用
this.OnPropertyChanged(nameof(Title)),或用
SetProperty(ref _title, value)(更推荐,自带相等性判断)
绑定到XAML:让UI真正“看见”变化
光有通知不够,XAML里得声明绑定关系。Avalonia默认支持
OneWay(ViewModel→View),多数场景够用: 单向显示:
<textblock text="{Binding Title}"></textblock>
双向编辑(如输入框):<textbox text="{Binding Title, Mode=TwoWay}"></textbox>
集合更新要额外注意:用
ObservableCollection<t></t>替代
List<t></t>,它自带
INotifyCollectionChanged,增删项会自动刷新
DataGrid或
ListBox
多线程更新UI:别在后台线程直接改属性
Avalonia的UI线程是单线程的。后台任务(比如
Task.Run)里直接赋值属性,UI不会刷新,甚至可能抛异常: 错误写法:
Task.Run(() => { Title = "加载完成"; }); // UI无反应
正确做法:用Dispatcher.UIThread.Post:
Task.Run(() => { var data = LoadFromApi(); Dispatcher.UIThread.Post(() => Title = data); });
进阶建议:把耗时操作封装在ReactiveCommand或
AsyncRelayCommand中,它们内置线程调度逻辑,更干净
调试小技巧:快速定位绑定失败
UI不更新?先看输出窗口(Output Window)有没有绑定错误日志:
检查DataContext是否已正确设置(常见于
MainWindow.axaml里漏写
DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}")
确认属性名拼写完全一致(大小写敏感,且不能是字段名,必须是公开属性名)
临时加断点验证OnPropertyChanged是否被调用;或用
Debug.WriteLine打日志
基本上就这些。不需要背接口细节,用好
ObservableObject和
[ObservableProperty],配合适当的XAML绑定模式和线程调度,UI就能稳稳跟着数据走。
