vb.netpropertygridexpandoobject

ExpandoObject PropertyChanged event not triggering in propertygrid


Basically I am loading a JSON object that contains combinations of values available or not at run time, so I need to know when a specific property is modified to then toggle all the other browsable etc.. and though that the PropertyChange event was the perfect way to handle it.

So I can add an event handler to get triggered on my expandoobject like this:

Dim test As Object = new ExpandoObject
  AddHandler CType(test, INotifyPropertyChanged).PropertyChanged, AddressOf expando_PropertyChanged

and the handler is as basic as it gets

Public Shared Sub expando_PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
    Debug.Print("Property {0} set or changed", e.PropertyName)
End Sub

so far this works, if I add or modify a property right after that, I get notified. however if I return this and set it as the selectedobject of my propertygrid, I cannot get the event to trigger.

I'm using a custom PropertyDescriptor and ICustomTypeDescriptor to set a few other attributes for the propertygrid, so I assumed it might be as easy as setting the attribute

<RefreshProperties(RefreshProperties.All)>

but I cannot find a way to override the Refresh in the PropertyDescriptor unlike Browsable or readonly, which kinda makes sense as the property grid would need to know ahead of time that it needs to be refreshable.


Solution

  • So I could not make the INotifyPropertyChanged work with the expando, it would work with a dynamicObject where I would implement it myself but that was requiring too much of a rewrite for me.

    I ended up add a lambda on my expando that I call on the PropertyDescriptor SetValue

          CType(_expando, Object).toggleSwitches.Invoke(_expando, _name, value)
    

    note the use of Invoke here in vb.net that was also a PITA but I found this guy who had the same issue as I did: https://github.com/dotnet/vblang/issues/226 It is not necessary to use invoke in C# and as 99% of the examples are in C# it took me more time than I wanted to implement it.

    Hopefully this will help someone too.

    here is the lambda if interested as well:

    _expando.toggleSwitches = Sub(obj As Object, caller As String, value As Object)
                           Debug.Print(caller & " " & value.ToString())
                         End Sub