Search code examples
c#.netpropertygridcollectioneditor

How to make CollectionEditor to fire CollectionChanged event when items added or removed?


I have this custom control that I grabbed from somewehere long ago:

public class NotifyingCollectionEditor : CollectionEditor
{
    // Define a static event to expose the inner PropertyGrid's PropertyValueChanged event args...
    public delegate void MyPropertyValueChangedEventHandler(object sender, PropertyValueChangedEventArgs e);
    public static event MyPropertyValueChangedEventHandler ElementChanged;

    // Inherit the default constructor from the standard Collection Editor...
    public NotifyingCollectionEditor(Type type) : base(type) { }

    // Override this method in order to access the containing user controls from the default Collection Editor form or to add new ones...
    protected override CollectionForm CreateCollectionForm()
    {
        // Getting the default layout of the Collection Editor...
        CollectionForm collectionForm = base.CreateCollectionForm();
        Form frmCollectionEditorForm = collectionForm as Form;
        TableLayoutPanel tlpLayout = frmCollectionEditorForm.Controls[0] as TableLayoutPanel;

        if (tlpLayout != null)
        {
            // Get a reference to the inner PropertyGrid and hook an event handler to it.
            if (tlpLayout.Controls[5] is PropertyGrid)
            {
                PropertyGrid propertyGrid = tlpLayout.Controls[5] as PropertyGrid;
                propertyGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(propertyGrid_PropertyValueChanged);
            }
        }

        return collectionForm;
    }

    void propertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
    {
        // Fire our customized collection event...
        var evt = NotifyingCollectionEditor.ElementChanged;

        if (evt != null)
            evt(this, e);
    }
}

It used to fire event when one of edited items in collection has changed, but I need it to fire even when some items were added or removed into this collection.

For now, I don't have other idea than compare amount of elements at creation of the form and at it's close.

But how I can access that edited collection to get it's Count value?

I tried to access propertyGrid.SelectedObject but it's null and even if it wasn't, I think there are collection items, instead of collection.


Solution

  • public class NotifyingCollectionEditor : CollectionEditor
    {
        // Define a static event to expose the inner PropertyGrid's PropertyValueChanged event args...
        public static event EventHandler<PropertyValueChangedEventArgs> ElementChanged;
    
        // Inherit the default constructor from the standard Collection Editor...
        public NotifyingCollectionEditor(Type type) : base(type) { }
    
        // Override this method in order to access the containing user controls from the default Collection Editor form or to add new ones...
        protected override CollectionForm CreateCollectionForm()
        {
            // Getting the default layout of the Collection Editor...
            CollectionForm collectionForm = base.CreateCollectionForm();
            Form frmCollectionEditorForm = collectionForm as Form;
            TableLayoutPanel tlpLayout = frmCollectionEditorForm.Controls[0] as TableLayoutPanel;
    
            if (tlpLayout != null)
            {
                // Get a reference to the inner PropertyGrid and hook an event handler to it.
                if (tlpLayout.Controls[5] is PropertyGrid)
                {
                    PropertyGrid propertyGrid = tlpLayout.Controls[5] as PropertyGrid;
                    propertyGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(propertyGrid_PropertyValueChanged);
                }
            }
    
            return collectionForm;
        }
    
        protected override object SetItems(object editValue, object[] value)
        {
            object ret_val = base.SetItems(editValue, value);
    
            // Fire our customized collection event...
            var evt = NotifyingCollectionEditor.ElementChanged;
    
            if (evt != null)
                evt(this, null);
    
            return ret_val;
        }
    
        void propertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
        {
            // Fire our customized collection event...
            var evt = NotifyingCollectionEditor.ElementChanged;
    
            if (evt != null)
                evt(this, e);
        }
    }
    

    Can do this.