![](/img/trans.png)
[英]How to programmatically add items to CollectionEditor's list/listbox/collection ? [modified]
[英]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.