PropertyGrid: Receive PropertyValueChanged notifications from CollectionEditor
The control is PropertyGrid
very useful for editing objects at runtime. I use it like this:
Form form = new Form();
form.Parent = this;
form.Text = "Editing MyMemberVariable";
PropertyGrid p = new PropertyGrid();
p.Parent = form;
p.Dock = DockStyle.Fill;
p.SelectedObject = _MyMemberVariable;
p.PropertyValueChanged += delegate(object s, PropertyValueChangedEventArgs args)
{
_MyMemberVariable.Invalidate();
};
form.Show();
As you can see, I am using notification PropertyValueChanged
to figure out when to update _MyMemberVariable
. However _MyMemberVariable
- this is a class that I did not write, and one of its members is a type Collection
. PropertyGrid
calls the Collection Editor to edit this type. However, when the collection editor is closed, I don't get a notification PropertyValueChanged
.
Obviously I could work around this problem by using ShowDialog()
and invalidating _MyMemberVariable
after the dialog is closed.
But I would like the events to PropertyValueChanged
fire when the collections have been edited. Is there a way to do this without changing _MyMemberVariable
(I don't have access to its source code)?
source to share
It's not very elegant, but it solved the problem I was having when someone updates / reorders a collection from a property grid:
propertyGrid1.PropertyValueChanged += (o, args) => PropertyGridValueChanged();
propertyGrid1.LostFocus += (sender, args) => PropertyGridValueChanged();
I am listening for an event LostFocus
when they click on something else. For my specific use case, this solution is sufficient. I think I mentioned this in case someone finds it useful.
source to share
I did some research and even reproduced the problem, however the solution I found doesn't help you, but I hope this information helps another person to help you.
Here
The problem is easily reproducible by creating a new window form project, adding a property grid and list to the form, and setting the list as the selected property grid object.
//designer code excluded
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
propertyGrid1.SelectedObject = listBox1;
propertyGrid1.PropertyValueChanged += delegate(object s, PropertyValueChangedEventArgs args)
{
MessageBox.Show("Invalidate Me!");
};
}
}
When editing a collection of list items, the event never fires, the reason is that the Items property returns a reference to the collection. Since adding items to the collection doesn't actually change the reference when the property never changes, hence the property grid.
The solution I tried was to extend the property grid and update the logic that compares the two and checks if the data in the collection has changed and raised an event. I tried this, but the PropertyGrid had an inner class PropertyGridView which was causing problems for me.
Hope this helps someone understand your problem.
-jeremy