INotifyPropertyChange events and Custom PropertyDescriptor

817 views Asked by At

I have a simple windows form application which uses a DataGridView bound to a BindingList<> of my custom object (MCO).

I have also implemented a custom TypeDescriptor and a custom PropertyDescriptor which I register against the type of MCO, for the purposes of providing more information on the DataGridView other then the default properties of MCO. The custom TypeDescriptor's PropertyDescriptorCollection returns the PropertyDescriptors from the parent (the default PropertyDescriptors for MCO) and one custom PropertyDescriptor.

All is well and when the DataGridView binds to the DataSource, the columns displayed correspond to those returned from the custom TypeDescriptor.

I have also implemented INotifyPropertyChanged on MCO so that the datagridview will refresh when the MCO properties are changed. However after three days of scouring the internet, and running all sorts of test code, I'm struggling to understand how to get the custom PropertyDescriptor to also participate in the INotifyPropertyChanged events.

As an example say MCO looks like this

Public Class MyCustomObject : INotifyPropertyChanged
{
   public int Property1 { get; set;}

   //typical INotifyPropertyChanged implementation
}

And then I add a Custom PropertyDescriptor "VirtualProperty2" via TypeDescriptor.AddProvider() which is mapped to Property1 via the getter and setter of the PropertyDescriptor.

When the DatagridView binds, it shows me Property1, and VirtualProperty2 as the two columns, and values of the cells are as expected.

If I then change the value of Property1 either by -

  1. Directly updating the Property 1 cell in the datagridview
  2. Directly updating the VirtualProperty2 cell in the datagridview
  3. Clicking a button on the form which updates a MCO.Property1 instance via code

The Property1 cell will refresh as expected. However VirtualProperty2 will only change through condition 2.

If I click on the cell of VirtualProperty2 after step 1 or 3, it will update. (Because clicking the cell must fire an event which calls the getter on the PropertyDescriptor)

Somehow I need the PropertyDescriptor for VirtualProperty1 to respond to the PropertyChanged event when Propery1 in the MCO fires it, because in effect VirtualPropery1 is mapped to Property1.

Ideas ?

1

There are 1 answers

0
l33t On

In your ICustomTypeDescriptor implementation, make sure that you cache the property descriptors. Without a cache you will get new - unbound - instances every time the method is called.

public PropertyDescriptorCollection GetProperties()
{
    if (propertyCache == null)
    {
        propertyCache = new PropertyDescriptorCollection(someProperties.ToArray<PropertyDescriptor>());
    }

    return propertyCache;
}