2014-10-16 5 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에 액세스하려고했지만 null이 아니며 그렇지 않은 경우에도 컬렉션 대신 컬렉션 항목이 있다고 생각합니다.

답변

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

가장 좋은 방법은 System.Collections.ObjectModel에 정의 된 ObservableCollection을 사용하는 것입니다. 이렇게하면 컬렉션을 추가하거나 제거 할 때 이벤트가 발생합니다. 이 클래스는 프레임 워크의 일부이므로 현재와 미래에 꽤 잘 작동합니다.

컬렉션 (T)의 형식을 모니터링하려면 해당 형식이 INotifyPropertyChanged를 구현해야합니다.