如何向PropertyGrid的CollectionEditor添加验证?

时间:2010-08-16 20:47:03

标签: c# winforms propertygrid collectioneditor

我正在使用PropertyGrid编辑包含集合的对象。 使用CollectionEditor编辑集合。 我必须确保集合中的元素是唯一的。

如何向CollectionEditor添加验证:

  1. 通过重载CollectionEditor的OnFormClosing
  2. 或者添加用于创建/编辑项目的验证?

2 个答案:

答案 0 :(得分:4)

您可以创建自己的集合编辑器,并在默认编辑器控件上挂钩事件。您可以使用这些事件来禁用“确定”按钮。类似的东西:

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

}

您还需要为您的集合添加Editor属性:

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

注意:我发现removeButton_Click中的项目值不正确 - 因此可能需要进行一些调整。

答案 1 :(得分:0)

尝试使用collectionForm.Context.Instance并将其强制转换为您的数据类型,这应该可以解决问题。