Wrapping my head around custom events

glasswizzard

Active member
Joined
Nov 22, 2019
Messages
30
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 :)
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
644
Location
Virginia Beach, VA
Programming Experience
10+
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?
It depends. If you want anybody who gets a reference to your event args object to mess with the values, then yes, you'll want the set to be public. Sometimes event args are meant to communicate one-way data (like a broadcast), while other event args are for two way communication between the event sender and the event receiver.

If you want it to be essentially readonly then make the set private. Modern OOP is starting to lean towards immutable objects instead of the data transfer objects of the 1990's and 2000's because of the rise of multi-threaded and parallel programming. It's easier to reason with objects that won't change under you.

Anyway if you want that setter to be private, you've got to be able to set the value somehow. That's when you use a constructor along with your event args object:
Code:
public class TextUpdatedEventArgs : EventArgs
{
    public string NewText { get; private set; }

    public TextUpdatedEventArgs(string newText)
    {
        NewText = newText;
    }
}
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,506
Location
Sydney, Australia
Programming Experience
10+
What I'm wondering is do I need both set and get? I think so right?
It's a property, like any other. When do you normally make a property read-only? When you want the data contained in the property to be able to be read but not over-written. Do you want the data in that property over-written? If not, it should be read-only.

Not sure whether you've seen my blog post on this subject or not but you might like to check it out if you haven't already.
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
644
Location
Virginia Beach, VA
Programming Experience
10+
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.
The key issue here is that you are using the UI as your data model. In modern programming techniques, you keep your data model separate from your view. The view (e.g. your UI)'s job is to reflect the current state of your data model to the user and give the user a way to interact with the data. Yes, back in the 70's through the early 90's it was common to use the UI as the data model as well as drive the business logic as well. (It's why there was a big market for all the whiz-bang widgets that all advertised that if you feed it the right data it would do all kinds of fancy graphs and analysis for you -- and might even cook you breakfast in the morning.) The reason why it used to be common to keep the data within the UI was the limited amount of memory and CPU processing power available back then. Every byte of memory mattered, so it didn't make sense to have the same data in two different places. So as great as this was in terms memory and CPU efficiency, it was really difficult to actually think of and reason with the data.

So the correct modern approach for the situation you are facing above is that your data model should consist of the list of history items. When Form1 is displayed it takes the last item in the list and shows it in the textbox. Whenever new text is typed into the textbox, the text is added to the list. When Form2 is displayed, it shows the items of the list in its listbox.
 

glasswizzard

Active member
Joined
Nov 22, 2019
Messages
30
Programming Experience
Beginner
It's a property, like any other. When do you normally make a property read-only? When you want the data contained in the property to be able to be read but not over-written. Do you want the data in that property over-written? If not, it should be read-only.

Not sure whether you've seen my blog post on this subject or not but you might like to check it out if you haven't already.
I've read your blog a couple of times over, it's a very good and clear description, it's helped me a lot to understand custom events, thanks for the link.

In C# 6.0 you can have readonly auto-property with only getter, which require constructor to set them: What's New in C# 6 - C# Guide
That's exactly what I need as it turns out. Thanks.

The key issue here is that you are using the UI as your data model. In modern programming techniques, you keep your data model separate from your view. The view (e.g. your UI)'s job is to reflect the current state of your data model to the user and give the user a way to interact with the data. Yes, back in the 70's through the early 90's it was common to use the UI as the data model as well as drive the business logic as well. (It's why there was a big market for all the whiz-bang widgets that all advertised that if you feed it the right data it would do all kinds of fancy graphs and analysis for you -- and might even cook you breakfast in the morning.) The reason why it used to be common to keep the data within the UI was the limited amount of memory and CPU processing power available back then. Every byte of memory mattered, so it didn't make sense to have the same data in two different places. So as great as this was in terms memory and CPU efficiency, it was really difficult to actually think of and reason with the data.

So the correct modern approach for the situation you are facing above is that your data model should consist of the list of history items. When Form1 is displayed it takes the last item in the list and shows it in the textbox. Whenever new text is typed into the textbox, the text is added to the list. When Form2 is displayed, it shows the items of the list in its listbox.
What you should be doing is adding the data from Form1 to a list of some sort and then populating the ListBox from that when Form2 is created and displayed.
I never thought about it in those terms before, it's very interesting, I'm going to redo it in that manner, thanks for the advice.

Edit: Quick question, to avoid my nemesis (scoping issues), where would be the correct place for such a list to be created?
 

Sheepings

Senior Programmer
Joined
Sep 5, 2018
Messages
652
Location
UK
Programming Experience
10+
If you have two forms, and you want to add a list, where would you put it?

Lets put it like this :
C#:
    public partial class Form1 : Form
    {
        public List<string> Lst_A = new List<string>();
        public Form1()
        {
            InitializeComponent();
        }
    }
How would you access each of these lists on either of the opposite form?
C#:
    public partial class Form2 : Form
    {
        public List<string> Lst_B = new List<string>();
        public Form2()
        {
            InitializeComponent();
        }
    }
Or would it be better to have a static list accessible in its own class from anywhere?

For example :
C#:
    public static class ListBoxList
    {
        static ListBoxList()
        {

        }
        public static List<string> Form2_ListBoxItems { get; set; }
    }
 

glasswizzard

Active member
Joined
Nov 22, 2019
Messages
30
Programming Experience
Beginner
If you have two forms, and you want to add a list, where would you put it?

Lets put it like this :
C#:
    public partial class Form1 : Form
    {
        public List<string> Lst_A = new List<string>();
        public Form1()
        {
            InitializeComponent();
        }
    }
How would you access each of these lists on either of the opposite form?
C#:
    public partial class Form2 : Form
    {
        public List<string> Lst_B = new List<string>();
        public Form2()
        {
            InitializeComponent();
        }
    }
Or would it be better to have a static list accessible in its own class from anywhere?

For example :
C#:
    public static class ListBoxList
    {
        static ListBoxList()
        {

        }
        public static List<string> Form2_ListBoxItems { get; set; }
    }
Well, the static list class definitely seems to be the best thing to do. I never thought about a list class, only a regular list. I'm not thinking like a programmer yet :/

Thanks very much for the advice, other questions on this topic (should they arise) I'll put in a new thread and keep my custom event questions here.
 
Top Bottom