Click here to Skip to main content
16,004,927 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
See more:
I create a panel and a button as below :
Panel ThePanel = New Panel();

Button TheButton = New Button();
TheButton.Click += new EventHandler(TheButton_Click);

When I click the Button, the click event will check if ThePanel eventhandler
has been created or not, if it has not been created, then create it. The code
in the click event, I suppose, should be as follow :
void TheButton_Click(object sender, EventArgs e)
{
    // (10 != 9) means (if ThePanel.LocationChanged is not created)
    if (10 != 9)
        ThePanel.LocationChanged += new EventHandler(ThePanel_LocationChanged);
}

And, in ThePanel_LocationChanged event, after having done the specific code, it will remove its LocationChanged event as follow :
void ThePanel_LocationChanged(object sender, EventArgs e)
{
    // do some specific code
    // ......
    
    ThePanel.LocationChanged -= new EventHandler(ThePanel_LocationChanged);

}

My question is :

In TheButton.Click event, how can I detect if ThePanel.LocationChanged event is created or not ? (ie the (10 != 9) should be replaced with correct lines)
Posted
Comments
Sergey Alexandrovich Kryukov 3-Jun-11 0:03am    
Pretty interesting question, I decided to up-vote it by 5.
--SA

Event handler can not be null or not, because event handler is a piece of code, a method, anonymous or not. Only the instance of event handle can be null or not.

When you implement an event in your class in C#, it is easy to do and you always need to do this check:
C#
public class MyEvenArguments : System.EventArgs { /*...*/ }

class MyEventTest {
    internal event EventHandler<myevenarguments< MyActionPerforming;
    internal event EventHandler<myevenarguments> MyActionPerformed;
    void MyAction() {
        if (MyActionPerforming != null)
            MyActionPerforming(this, new MyEvenArguments( /*...*/ ));
        //action
        if (MyActionPerformed != null)
            MyActionPerformed(this, new MyEvenArguments( /*...*/ ));
    } //MyAction
} //MyEventTest


However, outside of this class this check of impossible, even in the derived class:

C#
class MyEventTestDerived : MyEventTest {
    void Test() {
        if (this.MyActionPerformed != 0) //will not compile!
            System.Console.WriteLine("set up");
    }
}


That's it. Checking up if the event instance is null is impossible outside the class declaring the event.
This is one of the main limitations of the event instances compared to delegate instances. Events are designed to use limited and safe usage patterns.

There are no situations where checking up of the event instance for null could be useful. The users of the class firing event never fire the event. They can add an event handler to the event instance but cannot check up if it was done or not. This is the important conception of the event-oriented architecture. The user of the class firing the event cannot fire event, they call some method firing the event directly or indirectly and get called a callback called event handler if it happens. If an event handler is called, it means the event instance in not null, if not — we never need to know. If you're trying to create some algorithm based on this knowledge, you're trying to abuse the technology. You should be thankful to the event-oriented techniques for keeping you out of the abuse.

If you explain to me the ultimate goal of your code, I will be able to explain you how the goal should be reached without the effect you need.

I want to add something else. The whole idea of adding and removing an event handler in response to UI event is a sign of bad design. In good design you never remove event handler and set all your event handlers in the very beginning of the run time. For example, Form Designer puts sets up all the method InitializeComponent simply called from the form constructor. I never use Designer for setting up events (and recommend everyone to avoid this by all means and set events in your own code), but I also call the code setting my events from the Form constructor or in some other single call which happens in the beginning of run-time if this is not a Forms UI.

When you need to disable effect of the event handler call, you simply need a Boolean flag skipping a call. When event if fired, first action of the handler is to test this flag and exit immediately. This flag(s) can be a field of your class using the events; and you have fool control over it. In this way, you never need to add an event handler more than once and never need to remove it. This is a simple and reliable discipline.

—SA
 
Share this answer
 
v4
Comments
saxenaabhi6 2-Jun-11 23:15pm    
grt answer
Sergey Alexandrovich Kryukov 3-Jun-11 0:36am    
Thank you.
--SA
Sports Kuo 2-Jun-11 23:45pm    
Thanks so much of your prompt and detailed answers !

Yes, to use an extra flag for event detection should be more reasonable.

(plus, it seems be much late night on your site, isn't it ? You always work so hard, but, it's really helpful to us !)
Sergey Alexandrovich Kryukov 3-Jun-11 0:03am    
Thank you very much, Sports.

Yes, I'll need to sleep more tonight, thanks for asking. Thank you for your good works, but unfortunately, my advices are not helpful for many inquirers. I regret to say, I can see more and more members who are almost completely incapable of understanding and using any help. Some of them are even more active in asking their fruitless questions, the more frustration the get, the more they ask. It looks like a paradox, but this is similar to a well-known effect: you know some people loose everything because they try to get too much (in our cases, also with too little effort) or people who rush so much that they arrive too late (or rather never).

Thanks for accepting this answer (someone voted by the moment of writing, was that you?).

I hope you understand, the flag in not for detection of everything, it will just control the behavior of this particular handle: to act on event or not. That's all that matters for the application. The user of the event-firing class cannot effect event itself -- this is an important fool-proof limitation of the technology. That's why library components use events and not delegates -- to make the usage more fool-proof.

Good luck, call again.
--SA
Sports Kuo 3-Jun-11 1:38am    
fully understnading your deep-mind words, we get more not only the question-answer itself in this case. Congratulations to me to have this wonderful experience ! I'll follow your advise of fool-proof for the flag. Plus, I voted it now to indicate what I got for this.

here
is your solution i think
 
Share this answer
 
Comments
Sports Kuo 3-Jun-11 2:32am    
Thanks of your another solution, I'll try to study and undersnatnd it ...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900