Overwriting event handler

J

Jose Fernandez

hello.

i have a CheckSecurity method that does nothing but iterate thru every
Button control and, after a security level checking, i want to keep or
overwrite the Click event handler.

i can manually doit for one button and it works perfect. but i don't know
how many buttons i am gonna have or their instances name.
SO, i would like someone to address me in how to "find" the current
eventhandler for the control click event and change it for a method that i
have.

It would be something like...

foreach(Button b in this.Controls)
{
if(b.Text=="X")
{
b.Click-=new EventHandler(????????) -->> this is where i need to
know the name of the method.
b.Click += new EventHandler(X_Click)
}
}
 
J

Jon Skeet [C# MVP]

Jose Fernandez said:
i have a CheckSecurity method that does nothing but iterate thru every
Button control and, after a security level checking, i want to keep or
overwrite the Click event handler.

You can't. The point of an event is that the only options you have are
subscribing and unsubscribing, and you can only unsubscribe with
specific handlers.
 
J

Jose Fernandez

Well.. maybe this is not the way... but there has to be a way to know who
subscribed to an event in an object.
I am gonna try using reflection. There has to be a way.

i will keep you informed.
 
J

Jon Skeet [C# MVP]

Jose Fernandez said:
Well.. maybe this is not the way... but there has to be a way to know who
subscribed to an event in an object.

No, there isn't.
I am gonna try using reflection. There has to be a way.

Why? What makes you think there will definitely be a way? There's no
way of doing it in a totally general way, as events can be implemented
however the author chooses.

Note that even if you can find a way which works for the current
implementation of the classes you're interested in, there's nothing to
stop MS from changing the implementation in the future.

If you want to unsubscribe from events, you'll need to know what the
original subscriptions are. If you're responsible for all the
subscriptions, you can keep track of it yourself. If you're not, it's a
huge breakdown of encapsulation to unsubscribe someone else's handlers
for someone else's events.
 
J

Jose Fernandez

Ok. let me explain better

all i want is to change the name of the method in the Eventhandler to my
custom method IF some security criteria are not met. So, when the user
clicks on a button ('cause i want it to be able to be clicked) it will call
the design-time method or my method (which is a Supervisor Form). I can doit
inserting one line of code in every method definition in design time... but
that's a pain when i have more than 200 Forms and every form at least 2
buttons.
So, all i am creating is a base class that is the parent of every form, so i
check in every from that gets loaded its buttons.

I don't think that's something crazy.

Any idea?
 
R

RobinS

Why not just add code to the event handler that performs
a different action based on security level?

If securityLevel = "bestGuyOnThePlanet" Then
GiveHimAccessToTheWorld
Else
GiveHimAccessToTheCleaningSupplyCloset
End If

Or you could subscribe every button to two events,
and check the security level in the both events.

You know you can loop through all the controls and
assign event handlers to them? LIke I have one that
loops through all the controls and adds MouseEnter
and MouseLeave events to all the textboxes.

Robin S.
---------------------------
Jose Fernandez said:
Ok. let me explain better

all i want is to change the name of the method in the Eventhandler to my
custom method IF some security criteria are not met. So, when the user
clicks on a button ('cause i want it to be able to be clicked) it will
call the design-time method or my method (which is a Supervisor Form). I
can doit inserting one line of code in every method definition in design
time... but that's a pain when i have more than 200 Forms and every form
at least 2 buttons.
So, all i am creating is a base class that is the parent of every form, so
i check in every from that gets loaded its buttons.

I don't think that's something crazy.

Any idea?
 
J

Jose Fernandez

Well..

I want something that i can write once, and use in every form, in every
control.
I have already implementedIExtenderProvider to set the security values in
design time for every control in any forms that i load. Then, what i do, is
go to the database, fetch the security values for that user, store them in a
IPrincipal object that i created and everytime i load a form, i compare the
security values of the user with those in every control. That works
perfect!. I created a method in a base form, all my forms inherits from it.
So, when i load a form, i call that method, pass the parameters that i need
and voila... my controls appear enabled, disabled, visible... depends on the
criteria. So, one piece of code, 5 lines, just works for every form and
every control.

I wanted then, due to the ActionSecurityLevel, to be able to change in
runtime the method to be called when you click on a button. right? 'Cause i
don't wanna be writing code everytime i create a subscription to an event. I
know how to add in runtime an eventHandler to a control... as easy as
Control.[event]+=new System.EventHandler [or any other
handler](the_method_to_call). That's fine. But doesn't prevent the code to
perform any other method that had a subscription to that event.

So, i know also that you can programmatically unsubscribe an event by
Control.[event]-=.......... the problem is that when i am iterating thru
controls, i don't have the way to pass or know which handler[method] is
dealing with the subscription. I could do some trick. Like... once i hace
the control (in my iteration security checking code) i can find its instance
name, ok? lets say button1. ok. then i can ASSUME that when i created that
subscription it took by default the _Click suffix... so, it would be
button1_Click.
Next step would be to cast to Handler this string "button1_Click". So, i
would have to create a Method, returning a handler after i pass a parameter
type string with the "name" i "guess" it's going to have the handler. does
it makes sense?

let's put some pseudo code.

let's assume all controls are button.
foreach(Control c in form.Controls)
if(c.ActionSecurityLevel > User.ActionSecurityLevel)
c.click+=new system.EventHandler(myNonActionCode); --> we have here
added a new handler
c.click-=new system.EventHandler(????????); --> i can't write a
handler manually since you are iterating. i don't know the handler method
since i don't "know" its list of handlers. we can't access list of
suscription from the form to that control event.

MY "SILLY" SOLUTION

in that line of code (???????).. well i would set a method in there that
would return the eventhandler.

private EventHandler getEventHandler(string assumedName) -> remember,
assumed name is the concatenation of instance name of the control and
"_Click"

so, this method supposedly will return a handler with the name by default
that VS gives to a subscription to a click event. for example, for button
instance button1, would be button1_Click.

i know it sounds crazy but i think that funcionality would be great since i
don't have to worry about every button click event handler. if you can use
the button, go to its default handler. you can't? perform my code. DON"T
TELL ME DISABLE IT... cause what i want is to do "things" if that happens.
 
R

RobinS

Jose Fernandez said:
Well..

I want something that i can write once, and use in every form, in every
control.
I have already implementedIExtenderProvider to set the security values in
design time for every control in any forms that i load. Then, what i do,
is go to the database, fetch the security values for that user, store them
in a IPrincipal object that i created and everytime i load a form, i
compare the security values of the user with those in every control. That
works perfect!. I created a method in a base form, all my forms inherits
from it. So, when i load a form, i call that method, pass the parameters
that i need and voila... my controls appear enabled, disabled, visible...
depends on the criteria. So, one piece of code, 5 lines, just works for
every form and every control.

I wanted then, due to the ActionSecurityLevel, to be able to change in
runtime the method to be called when you click on a button. right? 'Cause
i don't wanna be writing code everytime i create a subscription to an
event. I know how to add in runtime an eventHandler to a control... as
easy as Control.[event]+=new System.EventHandler [or any other
handler](the_method_to_call). That's fine. But doesn't prevent the code to
perform any other method that had a subscription to that event.

So, i know also that you can programmatically unsubscribe an event by
Control.[event]-=.......... the problem is that when i am iterating thru
controls, i don't have the way to pass or know which handler[method] is
dealing with the subscription. I could do some trick. Like... once i hace
the control (in my iteration security checking code) i can find its
instance name, ok? lets say button1. ok. then i can ASSUME that when i
created that subscription it took by default the _Click suffix... so, it
would be button1_Click.
Next step would be to cast to Handler this string "button1_Click". So, i
would have to create a Method, returning a handler after i pass a
parameter type string with the "name" i "guess" it's going to have the
handler. does it makes sense?

let's put some pseudo code.

let's assume all controls are button.
foreach(Control c in form.Controls)
if(c.ActionSecurityLevel > User.ActionSecurityLevel)
c.click+=new system.EventHandler(myNonActionCode); --> we have here
added a new handler
c.click-=new system.EventHandler(????????); --> i can't write a
handler manually since you are iterating. i don't know the handler method
since i don't "know" its list of handlers. we can't access list of
suscription from the form to that control event.

MY "SILLY" SOLUTION

in that line of code (???????).. well i would set a method in there that
would return the eventhandler.

private EventHandler getEventHandler(string assumedName) -> remember,
assumed name is the concatenation of instance name of the control and
"_Click"

so, this method supposedly will return a handler with the name by default
that VS gives to a subscription to a click event. for example, for button
instance button1, would be button1_Click.

i know it sounds crazy but i think that funcionality would be great since
i don't have to worry about every button click event handler. if you can
use the button, go to its default handler. you can't? perform my code.
DON"T TELL ME DISABLE IT... cause what i want is to do "things" if that
happens.

I understand what you're going for, and I agree with the other people
who have posted -- I don't think it's possible to find the name of
an event handler that is assigned.

Maybe you could put the names in a table or something and access
them that way. I don't know if you can add a handler with a string
-- probably not.

Sorry; that's the best I can do. Good luck, and let us know if you
figure out a way to solve your problem. I'd be interested in what
you end up doing.

Robin S.
 
J

Jon Skeet [C# MVP]

Jose Fernandez said:
I want something that i can write once, and use in every form, in every
control.

<snip>

Not sure about the reflection solution - I'm trying to think of what
I'd do in your situation, but I guess I'd need to have more of an idea
of the initial reasoning.

I tend not to use designers, and there are various options which are
available when you *don't* use designers (like keeping track of all
your subscriptions in a separate map) but which aren't "designer
friendly".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top