I'm trying to edit collection of my own objects in the PropertyGrid. But I never reveive
PropertyValueChanged event after I edit collection in "Collection Editor" dialog and press Ok.
If I'm editing an array of objects I do receive PropertyValueChanged event.
I need to know when collection been changed so I can save it.
What I tried:
1) use array of objects. and I do get PropertyValueChanged notification and can save data. But I can not use ICustomTypeDescriptor, can not show my collection nicely in PropertyGrid. I can not inherit from array etc.
2) create and use my own collection, inherited from List<>, like described in example
http://www.codeproject.com/cs/miscctrl/customizingcollectiondata.asp
it shows stuff nicely, but I never receive PropertyValueChanged notification and can not save collection
3) I tried to create a collection inherited from CollectionBase or from IList<>. Attempt was to implement all Add/Insert/Remove methods by hand and fire my own event when something changed in collection. Unfortunately, PropertyGrid call Clear() and hundreds of Add() on almost any operation, like opening "Collection Editor" dialog or after pressing "Ok" or even "Cancel" button
Please help me!!!
here is sample code:
private
void Form1_Load(object sender, EventArgs e){
this.propertyGrid1.SelectedObject = newSelectedObject();}
privatevoid propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e){
Debug.Print("PropertyValueChanged {0}", e.ChangedItem.Label);}
classSelectedObject
{
// // PropertyGrid receives PropertyValueChanged notifications // when this property changed - good//
privateEmployee[] emp2;
publicEmployee[] EmpArray
{
get { return emp2; } set { emp2 = value; }}
// // PropertyGrid DO NOT receive any notifications // when this property changed - HOW CAN I FIX IT ??? // EmployeeCollection employees = newEmployeeCollection();
[
RefreshProperties(RefreshProperties.All)] publicEmployeeCollection Employees{
get { return employees; }}
}
[TypeConverter(typeof(EmployeeConverter))]
publicclassEmployee
{
privatestring firstName; publicstring FirstName { get { return firstName; } set { firstName = value; } } privatestring lastName; publicstring LastName { get { return lastName; } set { lastName = value; } }}
internal
classEmployeeConverter : ExpandableObjectConverter{
publicoverrideobject ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType){
if (destType == typeof(string) && value isEmployee){
Employee emp = (Employee)value;return emp.LastName + ", " + emp.FirstName;
}
returnbase.ConvertTo(context, culture, value, destType);}
}
[
TypeConverter(typeof(EmployeeCollectionConverter))]publicclassEmployeeCollection : List<Employee>, ICustomTypeDescriptor{
// all standart
ICustomTypeDescriptor Members, seehttp://www.codeproject.com/cs/miscctrl/customizingcollectiondata.asp
}// same class as in http://www.codeproject.com/cs/miscctrl/customizingcollectiondata.asp
publicclassEmployeeCollectionPropertyDescriptor : PropertyDescriptor
{
}