Tengo una función, void Validate()
, que contiene toda mi lógica de validación para una ventana.Implementación de un único controlador de eventos para controles múltiples con diferentes delegados controladores de eventos
No puedo simplemente registrar esto como un controlador de eventos porque no acepta los parámetros requeridos por los delegados del controlador de eventos. Además, los diferentes tipos de controles tienen diferentes firmas, por lo que no puedo hacer que Validate
coincida con una firma sin tener en cuenta su contenido.
Aquí es un pequeño ejemplo de lo que he configurar
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
}
Esto sólo muestra 2 ejemplos, más controles podrían tener incluso más firmas. ¿Hay alguna forma mejor de conseguir que todos los controladores de eventos invoquen una función en un caso en el que no me importan los argumentos que se pasan?
EDIT: me gusta la opción propuesta por Jon añadir los parámetros y simplemente ignorarlos. Eso soluciona la mayor parte del problema, pero cada vez que deseo llamar a esta función directamente, como para activar manualmente la validación, entonces tengo que incluir argumentos ficticios para satisfacer al compilador. ValidateOptions (esto, nuevos EventArgs())
La sugerencia que Dan hizo, para usar funciones anónimas, manejaría esto pero no está tan limpio cuando se asocian los controladores de eventos.
No parece que ninguna solución le permita registrar una función como controlador de eventos mientras ignora la firma y al mismo tiempo conserva la capacidad de invocar la función sin crear argumentos ficticios, pero hay muchas maneras de acercarse mucho.
EDIT:
Aquí está el ejemplo actualizado implementación de la solución de Jon como el manejo de eventos genéricos, pero manteniendo una función 0 parámetro que se puede llamar directamente
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
}
Incluso la firma 'void (objeto, objeto)' funcionaría en realidad. –
@ H.B.: Es cierto - Prefiero hacer que sea obvio que está ahí para el manejo de eventos :) –
@Jon Me gusta esto, y funcionó, pero luego me di cuenta de que olvidé parte del caso de uso en mi pregunta original (actualizado) . Una de las razones por las que la función Validate() aún no lo hizo es porque quería llamarlo para forzar la validación de otras funciones y con este enfoque simplifico el uso del controlador de eventos pero tengo que usar valores falsos cuando lo llamo directamente. – Eric