繁体   English   中英

如何在自定义集合编辑器中验证集合?

[英]How do I validate a collection in a custom collectioneditor?

我创建了一个自定义CollectionEditor但我想在用户单击“确定”按钮时验证我的集合。 我尝试了以下方法:

protected override CollectionForm CreateCollectionForm()
{
    _form = base.CreateCollectionForm();                        
    _form.FormClosing += _form_FormClosing;

    return _form;
}

因此,当用户单击“确定”时,它会触发 _form_Closing 事件。 但是,当我这样做时,这有效:

private void _form_FormClosing(object sender, FormClosingEventArgs e)
{
     e.Cancel = !Validate();                    
}

并且Validate返回false (告诉表单不要关闭)集合的所有现有成员都从UI中删除。 当然,集合的项目不应该从UI消失吗?

还有什么我需要打电话的吗?

好的,所以它不优雅,但确实有效。

像这样获取列表框

_listBox = _form.Controls[0].Controls[4] as ListBox;

将其存储为成员变量,然后像这样处理 OK 按钮上的 MouseDown 事件

Button btnOK = _form.AcceptButton as Button;            
btnOK.MouseDown += btnOK_MouseDown;

然后在类中创建一个对象列表或数组,并将它们复制到 MouseDown 上的数组中(你不能执行 MouseClick,因为那时它们已经消失了)。

void btnOK_MouseDown(object sender, MouseEventArgs e)
{
    _objects = new List<object>();

    foreach (object listItem in _listBox.Items)
    {
        _objects.Add(listItem);
    }           
}       

然后在 Form_Closing 上,如果集合未通过验证,则将它们重新添加。

if(!CheckValidEntities(_value as IEnumerable<Entity>))
{
    e.Cancel = true;

    foreach (object listItem in _objects)
    {
        _listBox.Items.Add(listItem);
    }                       
}

我不喜欢它,它有点笨拙,但似乎有效。

仍然是一个黑客,但这保留了对话框的状态。 无论按钮是用鼠标还是键盘单击,这都有效。

        protected override CollectionForm CreateCollectionForm()
        {
            this.Form = base.CreateCollectionForm();
            var okButton = this.Form.AcceptButton as Button;

            // replace the OK button current eventHandler.
            var okClickDelegate = this.RemoveClickEvent(okButton);
            okButton.Click += (sender, e) =>
            {
                // Validate your items
                var isValid = this.ValidateItems();
                if (isValid)
                {
                    okClickDelegate.DynamicInvoke(sender, e);
                }

                this.preventClose = !isValid;
            };
        }

        private void Form_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            e.Cancel = this.preventClose;

            this.preventClose = false;
        }

        /// <summary>
        /// Removes the click event handler of a button.
        /// </summary>
        /// <param name="b">The button to remove the click event.</param>
        /// <returns>A Delegate representing the remove event.</returns>
        private Delegate RemoveClickEvent(Button b)
        {
            FieldInfo f1 = typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);
            object obj = f1.GetValue(b);
            PropertyInfo pi = b.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
            EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);

            var handler = list[obj];

            list.RemoveHandler(obj, handler);

            return handler;
        }

删除事件的函数取自: https : //stackoverflow.com/a/91853/1698342

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM