I have a usercontrol with a TextBox
on it:
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;
}
}
I place the control and an ErrorProvider
on a form and do the following:
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);
}
}
When setting the delegate for the my control's Validating
event, it's setting the delegate for the UserControl
itself and not being overriden so that the event of the TextBox
will be set.
Shouldn't the above work as is? What am I missing?
It's not overriden, it's been shadowed or hidden by new
keyword. You haven't subscribed to the new event, you have subscribed for the base class event. It's basically how polymorphism works.
If you want to raise the Validating
event of the user control when a child control is validating, handle Validating
event of the child control and call OnValidating
method of the user control.
If you want to override the Validating
event override OnValidating
method.
If you want to change the sender of Validating
event, you need to change the way that Validating
event has been invoked. To do so, you need to use reflection and find the event and directly invoke it yourself.
Example - Raising Validating event of UserControl when Child control is validating
If you like to raise Validating
event of your control when the child text box is validating, handle Validating
event of the child control and call ``
public MyControl()
{
InitializeComponent();
txt.Validating += (obj, args) => OnValidating(args);
}
Example - Override Validating Event
protected override void OnValidating(CancelEventArgs e)
{
// Add custom code here.
base.OnValidating(e);
}
Example - Raising Validating
event manually without calling base.OnValidating
If for some reason you don't want to call base.OnValidating
, while its responsibility is basically raising the Validating
event, you can find the event and invoke it directly:
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);
}
Doing so, for example you can set another sender like the child control, instead of this
.