Assign once control event to event method

Asked

Viewed 88 times

3

I’m making a sequence of screens in the form, I have a main screen that loads other screens, the main screen is the Form1, and the subtleties will be the ones I will add on the main screen through the button, but when I click several times on button and start writing in TextBox, I realize there’s a performance drop.

I found that when I assign the event TextChanged of TextBox that is on the main screen for the method TextBox_TextChanged() of FormDefault and when typing a certain amount of times into the TextBox, the method TextBox_TextChanged() is called how many times I clicked on button formerly.

Example, I clicked 10 times on button to carry the FormDefault in the Form1 and entered the event of TextBox in the TextBox_TextChanged(), next time, when I write something on TextBox the method TextBox_TextChanged() will be called 10 times. Understand?

Imagine if this method makes a huge data query. This will get extremely slow.

public class Principal : Form
{
    public Principal()
    {
        InitializeComponent();
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        FormDefault cd = new FormDefault();
        this.textBox1.TextChanged += new EventHandler(cd.TextBox_TextChanged); // aqui esta o problema
        cd.TopLevel = false;
        cd.Visible = true;
        this.Controls.Clear();
        this.Controls.Add(cd);            
    }

    public class FormDefault : Form
    {
        public FormDefault()
        {
            InitializeComponent();
        }
        public void TextBox_TextChanged(object sender , EventArgs e)
        {
            // se apertar no button duas vezes, esse método será repetido duas vezes
        }

How do I assign only once the event TextChanged of TextBox to the method TextBox_TextChanged() when I press the button?

2 answers

4


In fact this makes no sense, if you put to perform something within a method that is called several times it will perform several times. You have to put this in a method that will be executed only once. What would this method be? It looks like it’s the constructor, right? Then put it in the Principal().

Probably will not give problem in this specific case because at the time this form closes probably the application closes together, but would in other cases, so at some point the correct is to turn off this event, this could be in a finalizer of this class, but this is another matter.

I’ve seen a lot of code leaking memory because of this, people think it’s GC failure or something, but it’s programmer failure that kept alive a reference to an object that’s not being used anymore.

  • I understand, I’m gonna rethink the code

1

Your code is causing the problem as it adds a new (new) event to every click of the button!

With each click on Button1 you add the event to the Textbox, the ideal would be to assign the event only once as quoted above by Maniero in Builder.

You can also remove the previous event and assign the (new) event, so just change the sign of += for -=

Example

//Remove o evento
this.textBox1.TextChanged -= TextBox_TextChanged; 
//Adiciona um (novo) evento
//this.textBox1.TextChanged += new EventHandler(cd.TextBox_TextChanged); 
//Adiciona o evento existente (não cria um novo "link")
this.textBox1.TextChanged += cd.TextBox_TextChanged; 

You can also see all associated events

foreach(Delegate d in TextBox_TextChanged.GetInvocationList())
{
    this.textBox1.TextChanged -= (TextBox_TextChanged)d;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.