Implement one event handler for multiple controls with different event handler delegates

I have a void Validate() function that contains all my validation logic for a window.

I cannot just register this as an event handler because it does not accept the parameters required by the event handler delegates. In addition, different types of controls have different signatures, so I cannot just Validate combine the same signature, ignoring their contents.

Here is a small example of what I installed

  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 } 

It just shows 2 examples, more controls can have even more signatures. Is there a better way to get all event handlers to call a function when I don't need the arguments passed in?


EDIT: I like the option John suggested to add parameters and just ignore them. This solves most of the problem, but anytime I want to call this function directly, for example, to manually trigger a check, I have to include dummy arguments to satisfy the compiler. ValidateOptions (this, new EventArgs ())

A Dan clause using anonymous functions will handle this, but is not as clean when binding event handlers.

It doesn't seem like any solution allows you to register a function as an event handler, ignoring the signature, and also retaining the ability to call the function without creating dummy arguments, but there are several ways to approach.


EDIT:

Here is an updated example of a Jon solution for handling common events, but retaining a parameter 0 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 } 
+6
source share
3 answers

You can have one method that ignores parameters:

 public void ValidateOptions(object sender, EventArgs e) { } 

The compiler will allow conversion from the group of ValidateOptions methods to any delegate type, following the normal event pattern, so that the first parameter is sender and the second parameter is some type obtained from EventArgs .

+6
source

You can use lambda expressions to reduce the amount of code you write for wrappers, although, behind the scenes, it still creates wrapper methods to discard parameters.

 txt3.TextChanged += (s,e) => ValidateOptions(); password2.PasswordChanged += (s,e) => ValidateOptions(); txt4.TextChanged += (s,e) => ValidateOptions(); 
+5
source

This handler provides one callback for wireframe controls, and the argument "e" is saved for consumption ...

  private static void EventHandlerSink(object sender, dynamic e) { } 
0
source

Source: https://habr.com/ru/post/901860/


All Articles