Wrapping my head around custom events

glasswizzard

Well-known member
Joined
Nov 22, 2019
Messages
126
Programming Experience
Beginner
Hi, here is the situation, Form1 has a TextBox, Form2 has a ListBox, the TextBox will send it's text string when it is updated (after a second of inactivity) and the ListBox will be updated with the text as a new item, a simple (hah!) history of the textbox's previous contents.
There is another event I'll need (to go in reverse, when a listbox item is double clicked, the string will go to the textbox) but I'll not ask about that, I'll keep it simple, I imagine once I know how to do one, I can do the other.

Here's what I understand so far (or think I do at least), please correct me if anything below is wrong.

So after reading the links provided in my other thread I know there are four steps to this:

1) Create the event arguments
2) Create an event that uses the arguments
3) Make a method to raise the event
4) Make a method to handle the raised event

So I'll stick with step 1 one for now, get some clarification, and use the example provided in the link to base my own on which I renamed and pasted below:

C#:
public class TextUpdatedEventArgs : EventArgs
{
    public string NewText { get; set; }
}

So the eventargs will just be a string (the new text in the textbox).

What I'm wondering is do I need both set and get? I think so right? Once the event is raised it will set the new text from the textbox as the event arguments and the listbox will get the text. Am I understanding this right?

Also, the link did not tell me where to put this code so I'm guessing it goes in the namespace section of my main forms cs file?

I'd like to add that this first part seems to be the most confusing for me, everything beyond this first point does seem much more understandable but I'll guess we'll find out if that's true :)
 
Oh I see, this is litterlaly the first time I'm hearing about unregistering events, I'm gonna need to look into that.
Registering an event handler creates a link between two objects that will prevent garbage collection occurring as quickly, so it is important to unregister to break that link.
 
I've edited the post, I renamed the event to ListBoxSelectionChanged and the handler to OnListBoxSelectionChanged, this matches how you named them in your blog post I think. I also got rid of the delegate.

The time to unsubscribe from this event I assume would be when form2 is closed right? But since the statement has to go in form 1's code, how would form1 know that form2 is closing?
 
I've edited the post, I renamed the event to ListBoxSelectionChanged and the handler to OnListBoxSelectionChanged, this matches how you named them in your blog post I think.
Nope. The method with the name of the event prefixed with "On" is the method that RAISES the event, not the method that HANDLES it. The OnListBoxSelectionChanged method should be in the same class as the ListBoxSelectionChanged event. The only place the event should be raised is in that method and you call that mehod when you want to raise the event. By doing that, any derived class can override that method and add custom functionality to be executed on that event and then raising the event from the base class will execute that functionality. If the class containing the event is never inherited then it doesn't really matter but I prefer to stick to the convention every time. That way, I can never accidentally not use that convention on an occasion that I should have.
The time to unsubscribe from this event I assume would be when form2 is closed right? But since the statement has to go in form 1's code, how would form1 know that form2 is closing?
You're calling ShowDialog. Once that method returns, the form has closed. That's the point. If you're calling Show then you can simply handle the FormClosed event as well.

By the way, a form displayed by calling ShowDialog is not disposed automatically so you should be doing it yourself. The way to do that is to create it with a using statement, so it is disposed at the end of the block.
 
Ok, let me make sure I have this down, so as for the naming convention when I wrote this:

C#:
form2.ListBoxSelectionChanged += OnListBoxSelectionChanged;

private void OnListBoxSelectionChanged(object sender, CustomEventArgs myArgs)
{
    TextBox1.Text = myArgs.ClickedText;
}

I'm using "On" in the wrong place, so I need to rename "OnListBoxSelectionChanged" because this is my method that handles the raised event. Is there a naming convention for this method? What do you think would a good name for it?

Also on that subject, I used the very generic name "CustomEventArgs" just as a clear example name for a custom event args class, obviously this is actually a bad name. I read (on your blog I think it was) that an event can be used whenever you need to utilize the data it can "carry". So in my example (even though I only have one use for it right now) my custom event args class will carry a single string, therefore I don't need to write a new eventargs class if I just need one string to be passed, I can always reuse this event for that.
That makes me wonder what the best way to name it would be. Do I name it based on it's data? Something like "SingleStringEventArgs" since that clearly describes the event arguments in my eyes and naming it based on it's function such as "ListBoxSelectionEventArgs" seems somewhat less clear in terms of the actual data it carries. Would either of those names be a good choice? Or would something else be better?
 
For the record, this is just a convention that no one is required to stick to, but I recommend sticking to it because consistency is always a good thing and you are then also doing things the same way as they are done in Framework code. I'll put together a full example but it might not be for a few hours, given that it is approaching 1.00 AM here right now.
 
For the record, this is just a convention that no one is required to stick to, but I recommend sticking to it because consistency is always a good thing and you are then also doing things the same way as they are done in Framework code. I'll put together a full example but it might not be for a few hours, given that it is approaching 1.00 AM here right now.

Did you finish the example? I may not have replied but I am eagerly awaiting it :)
 
Last edited by a moderator:
Back
Top Bottom