2010-08-16 1 views
3

PropertyGrid를 사용하여 컬렉션이 포함 된 개체를 편집하고 있습니다. CollectionEditor를 사용하여 컬렉션을 편집합니다. 컬렉션의 요소가 고유해야합니다.PropertyGrid의 CollectionEditor에 유효성 검사를 추가하는 방법은 무엇입니까?

어떻게 CollectionEditor에 유효성 검사를 추가 할 수 있습니다

  1. 을 하나 과부하 CollectionEditor의 OnFormClosing
  2. 또는 추가 검증하여/편집 항목을 만드는?

답변

3

자신 만의 컬렉션 편집기를 만들고 기본 편집기의 컨트롤에서 이벤트에 연결할 수 있습니다. 이러한 이벤트를 사용하여 OK (확인) 버튼을 비활성화 할 수 있습니다. 뭔가 같이 :

public class MyCollectionEditor : CollectionEditor 
{ 
    private static Dictionary<CollectionForm, Button> okayButtons 
     = new Dictionary<CollectionForm, Button>(); 

    // Inherit the default constructor from CollectionEditor 
    public MyCollectionEditor(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() 
    { 
     CollectionForm collectionForm = base.CreateCollectionForm(); 
     collectionForm.FormClosed += 
      new FormClosedEventHandler(collectionForm_FormClosed); 
     collectionForm.Load += new EventHandler(collectionForm_Load); 

     if (collectionForm.Controls.Count > 0) 
     { 
      TableLayoutPanel mainPanel = collectionForm.Controls[0] 
       as TableLayoutPanel; 
      if ((mainPanel != null) && (mainPanel.Controls.Count > 7)) 
      { 
       // Get a reference to the inner PropertyGrid and hook 
       // an event handler to it. 
       PropertyGrid propertyGrid = mainPanel.Controls[5] 
        as PropertyGrid; 
       if (propertyGrid != null) 
       { 
        propertyGrid.PropertyValueChanged += 
         new PropertyValueChangedEventHandler(
          propertyGrid_PropertyValueChanged); 
       } 

       // Also hook to the Add/Remove 
       TableLayoutPanel buttonPanel = mainPanel.Controls[1] 
        as TableLayoutPanel; 
       if ((buttonPanel != null) && (buttonPanel.Controls.Count > 1)) 
       { 
        Button addButton = buttonPanel.Controls[0] as Button; 
        if (addButton != null) 
        { 
         addButton.Click += new EventHandler(addButton_Click); 
        } 
        Button removeButton = buttonPanel.Controls[1] as Button; 
        if (removeButton != null) 
        { 
         removeButton.Click += 
          new EventHandler(removeButton_Click); 
        } 
       } 

       // Find the OK button, and hold onto it. 
       buttonPanel = mainPanel.Controls[6] as TableLayoutPanel; 
       if ((buttonPanel != null) && (buttonPanel.Controls.Count > 1)) 
       { 
        Button okayButton = buttonPanel.Controls[0] as Button; 
        if (okayButton != null) 
        { 
         okayButtons[collectionForm] = okayButton; 
        } 
       } 
      } 
     } 
     return collectionForm; 
    } 

    private static void collectionForm_FormClosed(object sender, 
     FormClosedEventArgs e) 
    { 
     CollectionForm collectionForm = (CollectionForm)sender; 
     if (okayButtons.ContainsKey(collectionForm)) 
     { 
      okayButtons.Remove(collectionForm); 
     } 
    } 

    private static void collectionForm_Load(object sender, EventArgs e) 
    { 
     ValidateEditValue((CollectionForm)sender); 
    } 

    private static void propertyGrid_PropertyValueChanged(object sender, 
     PropertyValueChangedEventArgs e) 
    { 
     ValidateEditValue((CollectionForm)sender); 
    } 

    private static void addButton_Click(object sender, EventArgs e) 
    { 
     Button addButton = (Button)sender; 
     ValidateEditValue((CollectionForm)addButton.Parent.Parent.Parent); 
    } 

    private static void removeButton_Click(object sender, EventArgs e) 
    { 
     Button removeButton = (Button)sender; 
     ValidateEditValue((CollectionForm)removeButton.Parent.Parent.Parent); 
    } 

    private static void ValidateEditValue(CollectionForm collectionForm) 
    { 
     if (okayButtons.ContainsKey(collectionForm)) 
     { 
      Button okayButton = okayButtons[collectionForm]; 
      IList<MyClass> items = collectionForm.EditValue as IList<MyClass>; 
      okayButton.Enabled = MyCollectionIsValid(items); 
     } 
    } 

    private static bool MyCollectionIsValid(IList<MyClass> items) 
    { 
     // Perform validation here. 
     return (items.Count == 2); 
    } 

} 

또한 수집 당신에게 편집기의 속성을 추가해야합니다

class MyClass 
{ 
    [Editor(typeof(MyCollectionEditor), 
      typeof(System.Drawing.Design.UITypeEditor))] 
    List<Foo> MyCollection 
    { 
    get; set; 
    } 
} 

참고 : 내가 removeButton_Click 항목의 값이 올바르지 않은 것을 발견했다 - 그래서 일부 조정을 일어나야 할 수도 있습니다.

+0

collectionForm_FormClosing 함수에서 편집중인 컬렉션 항목에 어떻게 액세스 할 수 있습니까? collectionForm.Items protected :( 항목의 이름 속성이 고유한지 확인해야합니다. – JBeurer

+0

MyCollectionEditor에서 this.GetItems()를 호출 할 수 있어야합니다. (직접 시도하지는 않았지만) –

+0

참으로 있습니다. CollectionEditor에서 GetItems() 함수, 그러나 그것은 MSDN에 따르면 나에게 많은 이해가되지 않습니다 하나 개의 인수, 보호 된 가상 객체 [] GetItems ( \t 객체 editValue ) 있습니다. editValue -에 컬렉션을 편집 매우 자세한 설명서 컬렉션에 대한 액세스 권한은 처음에는 문제입니다. : – JBeurer

0

collectionForm.Context.Instance를 시도하고 트릭을 수행해야하는 데이터 유형으로 유형을 변환하십시오.