我有一个带有TextBox
的用户控件:
public partial class MyControl : UserControl
{
public new event CancelEventHandler Validating
{
add
{
txt.Validating += value;
}
remove
{
txt.Validating -= value;
}
}
public new string Text
{
get => txt.Text;
set => txt.Text = value;
}
}
我将控件和ErrorProvider
放在表单上,然后执行以下操作:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
SetErrorEvents(myControl1);
}
private void SetErrorEvents(object control)
{
(control as Control).Validating += ValidationEvent;
}
private void ValidationEvent(object sender, CancelEventArgs e)
{
var control = (Control)sender;
if (string.IsNullOrWhiteSpace(control.Text))
errorProvider1.SetError(control, "error");
else
errorProvider1.SetError(control, string.Empty);
}
}
在为我的控件的Validating
事件设置委托时,它是为UserControl
本身设置委托,并且不会被覆盖,因此将设置TextBox
的事件。 / p>
以上工作不是应该的吗?我想念什么?
答案 0 :(得分:2)
它未被覆盖,已被new
关键字遮盖或隐藏。您尚未订阅新事件,您已经订阅了基类事件。基本上就是polymorphism的工作方式。
如果要在验证子控件时引发用户控件的Validating
事件,请处理该子控件的Validating
事件并调用该控件的OnValidating
方法用户控制。
如果您要覆盖Validating
事件覆盖OnValidating
方法。
如果要更改Validating
事件的发送者,则需要更改Validating
事件的调用方式。为此,您需要使用反射并找到事件,然后直接自己调用它。
示例-子控件验证时引发UserControl的验证事件
如果您希望在验证子文本框时引发控件的Validating
事件,请处理子控件的Validating
事件并调用``
public MyControl()
{
InitializeComponent();
txt.Validating += (obj, args) => OnValidating(args);
}
示例-覆盖验证事件
protected override void OnValidating(CancelEventArgs e)
{
// Add custom code here.
base.OnValidating(e);
}
示例-手动引发Validating
事件而无需调用base.OnValidating
如果由于某种原因您不想调用base.OnValidating
,而它的职责基本上是引发Validating
事件,则可以找到该事件并直接调用它:
protected override void OnValidating(CancelEventArgs e)
{
var f = typeof(Control).GetField("EventValidating",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Static);
var validating = (CancelEventHandler)Events[f.GetValue(this)];
validating?.Invoke(this, e);
}
例如,您可以设置另一个发件人,例如子控件,而不是this
。
答案 1 :(得分:1)
定义此接口:
public interface IMyControl
{
event CancelEventHandler Validating;
}
将界面应用于自定义控件:
public partial class MyControl : UserControl, IMyControl
{
...
}
在您的Form
类中,更新SetErrorEvents()
,以便将其强制转换为IMyControl
:
...
private void SetErrorEvents(object control)
{
(control as IMyControl).Validating += ValidationEvent;
}
...