I have a function, void Validate()
, that contains all my validation logic for a window.
I can't simply register this as an event handler because it doesn't accept the parameters required by the event handler delegates. Additionally different types of controls have different signatures so I can't just have Validate
match one signature while ignoring their contents.
Here is a small example of what I've setup
txt1.TextChanged += Validate_TextChange;
password1.PasswordChanged += Validate_RoutedEvent;
txt2.TextChanged += Validate_TextChange;
txt3.TextChanged += Validate_TextChange;
password2.PasswordChanged += Validate_RoutedEvent;
txt4.TextChanged += Validate_TextChange;
void Validate_RoutedEvent(object sender, RoutedEventArgs e)
{
ValidateOptions();
}
void Validate_TextChange(object sender, TextChangedEventArgs e)
{
ValidateOptions();
}
public void ValidateOptions()
{
//Actual validation here
}
This just shows 2 examples, more controls could have even more signatures. Is there any better way of getting all event handlers to call a function in a case where I don't care about the arguments being passed?
EDIT: I like the option proposed by Jon to add the parameters and simply ignore them. That does solve most of the problem but anytime I want to call this function directly, such as to manually trigger validation, I then have to include dummy arguments to satisfy the compiler. ValidateOptions(this, new EventArgs())
The suggestion Dan made, to use anonymous functions, would handle this but isn't as clean when associating the event handlers.
It doesn't appear that either solution lets you register a function as an event handler while ignoring the signature while also preserving the ability to call the function without creating dummy arguments but there are multiple ways to get pretty close.
EDIT:
Here is the updated example implementing Jon's solution for generic event handling but keeping a 0 parameter function that can be called directly
txt1.TextChanged += ValidationEvent;
password1.PasswordChanged += ValidationEvent;
txt2.TextChanged += ValidationEvent;
txt3.TextChanged += ValidationEvent;
password2.PasswordChanged += ValidationEvent;
txt4.TextChanged += ValidationEvent;
//Single event handler accepting EventArgs, which is the base class
//for all more-specific event classes
void ValidationEvent(object sender, EventArgs e)
{
//Ignores arguments and calls 0 argument ValidateOptions
ValidateOptions();
}
//0 argument function that performs actual validation and can be called
//directly from other functions without the need to pass in a fake sender
//and eventargs parameter
public void ValidateOptions()
{
//Actual validation here
}
You can have a single method which ignores the parameters:
public void ValidateOptions(object sender, EventArgs e)
{
}
The compiler will allow a conversion from the ValidateOptions
method group to any delegate type following the normal event pattern such that the first parameter is sender
and the second parameter is some type derived from EventArgs
.
You can use lambda expressions to reduce the amount of code you write for wrappers, though, behind the scenes, it's still creating wrapper methods to discard the parameters.
txt3.TextChanged += (s,e) => ValidateOptions();
password2.PasswordChanged += (s,e) => ValidateOptions();
txt4.TextChanged += (s,e) => ValidateOptions();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With