2014-10-16 3 views
2

У меня есть этот пользовательский элемент управления, который я схватил из somewehere давно:Как сделать CollectionEditor для запуска события CollectionChanged, когда элементы добавлены или удалены?

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); 
    } 
} 

Он используется огонь событие, когда один из редактируемых элементов в коллекции изменилась, но мне нужно, чтобы стрелять, даже когда были добавлены некоторые элементы или удалены в эту коллекцию.

На данный момент у меня нет другой идеи, кроме сравнения количества элементов при создании формы и при ее закрытии.

Но как я могу получить доступ к этой отредактированной коллекции, чтобы получить ее значение Count?

Я попытался получить доступ к propertyGrid.SelectedObject, но это не так, и даже если это не так, я думаю, что есть коллекции, а не коллекция.

ответ

1
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); 
    } 
} 

Может это сделать.

1

Лучше всего использовать ObservableCollection, определенные в System.Collections.ObjectModel. Это вызовет события, когда коллекция будет добавлена ​​или удалена. Этот класс является частью структуры и поэтому должен работать очень хорошо, теперь и в будущем.

Если вы хотите контролировать тип в коллекции (T), тогда этому типу придется реализовать INotifyPropertyChanged.