AvaloniaUI动态XAML绑定ExpandoObject属性不更新问题
解决Avalonia中动态属性绑定ExpandoObject失效的问题
问题根源
Avalonia的绑定引擎依赖静态属性元数据(反射或TypeDescriptor)解析绑定路径,而ExpandoObject的动态属性无法被该引擎正确识别,导致出现Could not find a matching property accessor错误,同时属性变更也无法被绑定系统监听。
解决方案:自定义动态属性容器
替换ExpandoObject为继承DynamicObject并实现INotifyPropertyChanged的自定义类,手动处理属性读写和变更通知,让Avalonia绑定系统能正确识别动态属性。
1. 创建自定义动态属性类
using System.ComponentModel; using System.Dynamic; using System.Runtime.CompilerServices; public class DynamicPropertyBag : DynamicObject, INotifyPropertyChanged { private readonly Dictionary<string, object?> _properties = new(); public event PropertyChangedEventHandler? PropertyChanged; // 处理动态属性读取逻辑 public override bool TryGetMember(GetMemberBinder binder, out object? result) { return _properties.TryGetValue(binder.Name, out result); } // 处理动态属性写入逻辑,触发变更通知 public override bool TrySetMember(SetMemberBinder binder, object? value) { _properties[binder.Name] = value; OnPropertyChanged(binder.Name); return true; } // 提供索引器,方便绑定系统访问属性 public object? this[string key] { get => _properties.TryGetValue(key, out var val) ? val : null; set { _properties[key] = value; OnPropertyChanged(key); } } private void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 更新ViewModel
将原ExpandoObject替换为自定义的DynamicPropertyBag:
using CommunityToolkit.Mvvm.ComponentModel; using System.Diagnostics; namespace DynamicBindingControls.ViewModels; public partial class DynamicSettingsGroupVM : ViewModelBase { [ObservableProperty] private string _name; // 替换为自定义动态属性容器 public dynamic DynamicSettingsProperties { get; set; } = new DynamicPropertyBag(); public DynamicSettingsGroupVM(string aName) { Name = aName; ((INotifyPropertyChanged)DynamicSettingsProperties).PropertyChanged += HandlePropertyChanges; } private void HandlePropertyChanges(object? sender, PropertyChangedEventArgs e) { var bag = DynamicSettingsProperties as DynamicPropertyBag; Trace.WriteLine($"{e.PropertyName} has changed to {bag?[e.PropertyName]}."); } }
3. 调整绑定方式
使用索引器语法绑定动态属性,确保Avalonia能正确解析路径:
public void CreateDynamicSettings() { var myDC = DataContext as ViewModels.DynamicSettingsGroupVM; var props = myDC.DynamicSettingsProperties as DynamicPropertyBag; props["DynaProp"] = "Brand new"; // 使用索引器语法绑定动态属性 var settingField = new TextBox { [!TextBox.TextProperty] = new Binding("DynamicSettingsProperties['DynaProp']") }; stpDynamicFields.Children.Add(settingField); }
验证效果
运行应用后:
- TextBox会正确显示初始值
Brand new - 修改TextBox内容时,调试日志会输出属性变更信息
- 绑定的双向同步功能正常工作
内容的提问来源于stack exchange,提问作者Eric Eggers
相关产品推荐
相关产品推荐

