如何向 PropertyGrid 的 CollectionEditor 添加验证?

发布于 2024-09-14 10:19:47 字数 197 浏览 4 评论 0原文

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

如何向 CollectionEditor 添加验证:

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

I'm using PropertyGrid to edit an object containing a collection.
Collection is edited using the CollectionEditor.
I have to make sure elements in collection are unique.

How can I add validation to CollectionEditor:

  1. By either overloading CollectionEditor's OnFormClosing
  2. Or adding validation for creating/editing items?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蔚蓝源自深海 2024-09-21 10:19:47

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

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 中的项目值不正确 - 因此可能需要进行一些调整。

You can create your own collection editor, and hook into events on the default editor's controls. You can use these events to, say, disable the OK button. Something like:

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

}

You will also need to add an Editor attribute to you collection:

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

NOTE: I found that the value of items in removeButton_Click was not correct - so some tweaking may need to take place.

东风软 2024-09-21 10:19:47

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

Try collectionForm.Context.Instance and typecast it to your data type this should do the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文