You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExpandoObject绑定PropertyGrid后PropertyChanged事件未触发问题

问题根因

ExpandoObject 原生实现的 INotifyPropertyChanged 机制本身没有问题,事件无法触发的核心原因是属性通知链被自定义类型描述层隔断了:

  • 直接给 ExpandoObject 挂载事件时,只有直接操作 ExpandoObject 实例本身增删改属性,才会触发原生通知
  • 当你通过自定义 ICustomTypeDescriptor、PropertyDescriptor 封装实例再绑定给 PropertyGrid 时,PropertyGrid 对属性的所有读写操作都是通过你返回的 PropertyDescriptor 层完成的,不会直接和底层 ExpandoObject 交互,原生的属性变更事件自然不会触发
  • 你尝试添加的 <RefreshProperties(RefreshProperties.All)> 特性不生效的逻辑也很直接:这个特性的作用是告知 PropertyGrid “当前属性修改后需要刷新全表”,生效前提是 PropertyGrid 能捕获到当前属性的变更动作,现在变更通知都传不到 PropertyGrid,加特性自然没有效果。这个特性不需要在 PropertyDescriptor 里重写特殊逻辑,只要把它加到你自定义 PropertyDescriptor 的特性集合里就能被正常识别,核心问题始终是通知链断裂。
落地解决方案
  • 方案一(最稳妥,推荐):放弃直接绑定原生 ExpandoObject,自己写一个动态包装类,同时实现 ICustomTypeDescriptor 和 INotifyPropertyChanged 接口,内部用字典维护所有属性值、属性的可浏览/只读等状态。
    在自定义 PropertyDescriptor 的 SetValue 方法里,写完属性值后主动触发包装类的 PropertyChanged 事件;如果修改的是需要联动其他属性状态的触发属性,直接调用 PropertyGrid 实例的 Refresh() 方法强制刷新,完全不需要依赖 ExpandoObject 自带的通知逻辑,可控性最高。
    核心逻辑参考代码:
    Public Overrides Sub SetValue(component As Object, value As Object)
        ' 更新内部属性值存储
        _internalValueStore(_currentPropertyName) = value
        ' 触发当前属性的变更通知
        Dim wrapper = CType(component, DynamicWrapper)
        wrapper.RaisePropertyChanged(_currentPropertyName)
    
        ' 如果当前属性是联动触发属性,更新其他属性的Browsable/ReadOnly状态后刷新网格
        If _isLinkageTrigger Then
            UpdateOtherPropertyStates() ' 自定义联动状态更新逻辑
            _boundPropertyGrid.Refresh()
        End If
    End Sub
    
  • 方案二(保留原生ExpandoObject的适配写法):如果一定要用原生 ExpandoObject 作为底层存储,就不要在外部给 ExpandoObject 挂事件,把事件监听和触发逻辑放到自定义 PropertyDescriptor 里。
    在重写的 SetValue 方法中,先把值写入 ExpandoObject 对应的属性,再主动抛出 PropertyChanged 通知,同时给需要触发全表刷新的 PropertyDescriptor 加上 <RefreshProperties(RefreshProperties.All)> 特性,PropertyGrid 识别到特性后,在属性修改完成后会自动重拉所有属性的状态,完成联动更新。

注意:不需要找 PropertyDescriptor 里和 Refresh 相关的可重写方法,RefreshProperties 是通过特性元数据识别的标记,没有对应的可重写逻辑,只要把特性正确加到 PropertyDescriptor 的特性列表里就完成了这部分配置。

内容的提问来源于stack exchange,提问作者Adrien Rochereau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:45:49