Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event handlers in c# - syntax/pattern

I'm new to c# so apologies if this is a noob question. I'm trying to get clarity around the syntax or pattern for handling events in c#.

So I have a Form object Form1 and a Button button1 in the form. I handle a Click event with a method like this in Form1.cs:

private void button1_Click(object sender, EventArgs e)
{
    Debug.WriteLine("click!");
}

which works fine. Now in another form Form2 I have a TreeView treeView1, and I want to handle the BeforeExpand event. So I assumed it would be:

private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
     Debug.WriteLine("Hello!");
}

which in fact doesn't work: this method is never called when I expand a node. But several SO answers imply this is the way to do it, e.g this one.

Anyway I found an alternative approach which does work for me. In the form constructor bind the event handler like this:

treeView1.BeforeExpand += new TreeViewCancelEventHandler(anyMethodNameYouLike);

So what's the difference between these two approaches? Why doesn't the _event syntax work for a treeview? Is there some difference between the event types?

Thanks

like image 788
Richard H Avatar asked Nov 08 '11 20:11

Richard H


6 Answers

I assume you doubleclicked the button in the Visual Studio designer. The button1_Click handler got added automatically, just like you created the BeforeExpand handler by hand.

Check your Form1.Designer.cs file, you'll find a line something like this:

this.button1.Click += new System.EventHandler(this.button1_Click);
like image 137
Abel Avatar answered Oct 19 '22 21:10

Abel


You need both things:
1) a method that can handle the type of event in question. For a TreeViewCancelEventHandler(MSDN) delegate the correct method signature is:

public void MyMethodNameGoesHere(Object sender,TreeViewCancelEventArgs e)
{
  // do some impressive stuff here
}

2) you have to register for the event:

treeView1.BeforeExpand += new TreeViewCancelEventHandler(MyMethodNameGoesHere);

You could also use just the method name:

treeView1.BeforeExpand += MyMethodNameGoesHere;

And as a last alternative you might use this 'inline' syntax for small functions:

treeView1.BeforeExpand += (sender, e) =>
{
    // do a bit of magic here
};

What is possibly good to know is that handler registrations don't 'stack' (sorry for the poor wording, suggestions for improvement are very welcome!). Meaning when you do the following you will not receive further events after the last line has executed:

treeView1.BeforeExpand += MyMethodNameGoesHere;
treeView1.BeforeExpand += MyMethodNameGoesHere;
treeView1.BeforeExpand += MyMethodNameGoesHere;
treeView1.BeforeExpand -= MyMethodNameGoesHere; // note the MINUS sign
like image 44
yas4891 Avatar answered Oct 19 '22 20:10

yas4891


What you have is correct. You need to add the the handler to the event as you have done in the second case.

There must be a line like this:

button1.Click += button1_Click;

(possibly with a new EventHandler() wrapper) somewhere in your Form1 code, most probably in the .designer.cs file.

like image 29
ChrisF Avatar answered Oct 19 '22 19:10

ChrisF


The first syntax, which isn't syntax at all, is just a naming convention for event handlers. What you're doing with the second syntax is setting up a delegate to an event handler and adding it to that event.

If you check Form1, and click select the Button and look at its events properties, the event is most likely hooked up through the designer. You could do the same with the TreeView on its form, through the designer.

like image 44
Joshua Rodgers Avatar answered Oct 19 '22 20:10

Joshua Rodgers


The C# event handling system does not work on any sort of naming convention (I think you may believe this to be the case?). A method called treeView1_BeforeExpand will not be called on treeview1's BeforeExpand event unless you tell it to call that method on that particular event.

The code below says "when the BeforeExpand event is fired, invoke the anyMethodNameYouLike method.

treeView1.BeforeExpand += new TreeViewCancelEventHandler(anyMethodNameYouLike);

You have to write your anyMethodNameYouLike method.

like image 1
AndrewC Avatar answered Oct 19 '22 19:10

AndrewC


In WinForms, you can bind event handlers from the designer using the "properties" toolbox and clicking the lightning button at the top. This will open the events tab. Just double click on the name of an event to generate an handler in your code or select an existing method with the right signature from the dropdown. This will actually generate the "+=" code for you in the .designer file.

The name Control_Event is automatically generated. However, you can use any name for your handlers and even register more than one.

like image 1
Kevin Coulombe Avatar answered Oct 19 '22 21:10

Kevin Coulombe