You are using the PropertyGrid
control to allow the user to edit the properties of an object at run-time from the UI. This works great and is in fact very reliable since this is the same control used by Visual Studio to display the properties of controls. Now that you are letting the user update the object directly, you'd like to get a PropertyValueChanged
event whenever the user changes a property, so you can respond to the user’s action. You'll be able to do that by adding a PropertyValueChanged
event to the PropertyGrid
, which will get triggered every time a property is changed, unless the property is a collection. So if you have a collection inside the property grid selected object and you'd like to be notified when a property changes in that collection or when an item is added\removed, there is no way to do so with the OOB Microsoft PropertyGrid
control. Clearly, the reason why the PropertyValueChanged
event is not triggered when a collection is changed is because the reference to the collection object is still the same.
In order to be notified when a property changes inside a collection, follow instructions on this blog. You'll find this very helpful. However, this solution can't help you if you'd like to be notified when an item is removed from the collection or when it is added without any of its properties changed. A more generic solution I found was to get a notification when the collection form is closed. This way, I wouldn't have to worry too much about the steps the user is taking in the collection editor. When the collection form is closed, I get notified and act on the collection object based on its current state.
Solution
First, add a reference to System.Design DLL in your Visual Studio project. Create the following class, which represents a collection editor that triggers a MyFormClosed
event when the collection editor form is closed.
using System;
using System.ComponentModel.Design;
using System.Windows.Forms;
public class MyCollectionEditor : CollectionEditor
{
public delegate void MyFormClosedEventHandler(object sender,
FormClosedEventArgs e);
public static event MyFormClosedEventHandler MyFormClosed;
public MyCollectionEditor(Type type) : base(type) { }
protected override CollectionForm CreateCollectionForm()
{
CollectionForm collectionForm = base.CreateCollectionForm();
collectionForm.FormClosed += new FormClosedEventHandler(collection_FormClosed);
return collectionForm;
}
void collection_FormClosed(object sender, FormClosedEventArgs e)
{
if (MyFormClosed != null)
{
MyFormClosed(this, e);
}
}
}
To use the above collection editor for the property grid, you can simply add the following attribute above the collection Property
of the object which you set to propertGrid.SelectedObject
.
[Editor(typeof(MyCollectionEditor), typeof(UITypeEditor))]
The final part is to create our custom FormClosed
event handler and bind it to our custom collection editor as follows:
public MyForm()
{
InitializeComponent();
MyCollectionEditor.MyFormClosed += new MyCollectionEditor.MyFormClosedEventHandler
(propertyGrid_CollectionFormClosed);
}
private void propertyGrid_CollectionFormClosed(object s, FormClosedEventArgs e)
{
}
Posted in .NET, C# Tagged: collection, collection editor, CollectionEditor
, event, FormClosed
, FormClosedEventHandler
, propertygrid
, propertyvaluechanged
, PropertyValueChangedEventHandler
CodeProject