-1

Please help me to understand the following problem.

I have a demo C# wiforms .net project. I have a numericUpDown_ValueChanged event which works. If I click the button1 I remove that event from the numeric. So this event does not work anymore. When I click button2 I call the InitializeComponent method.

Question: Why does this not recreate the event for my numericUpDown control? Is there any opportunity to assign the event back to the control?

I don't want to do this with:

numericUpDown1.ValueChanged += numericUpDown1_ValueChanged;

My Code

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
        numericUpDown1.ValueChanged -= numericUpDown1_ValueChanged;
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
        Console.WriteLine(numericUpDown1.Value);
    }

    private void button2_Click(object sender, EventArgs e) {
        InitializeComponent();
    }
}

My .Designer File

partial class Form1 {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing) {
        if (disposing && (components != null)) {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent() {
        this.button1 = new System.Windows.Forms.Button();
        this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
        this.button2 = new System.Windows.Forms.Button();
        ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
        this.SuspendLayout();
        // 
        // button1
        // 
        this.button1.Location = new System.Drawing.Point(80, 139);
        this.button1.Name = "button1";
        this.button1.Size = new System.Drawing.Size(75, 23);
        this.button1.TabIndex = 0;
        this.button1.Text = "button1";
        this.button1.UseVisualStyleBackColor = true;
        this.button1.Click += new System.EventHandler(this.button1_Click);
        // 
        // numericUpDown1
        // 
        this.numericUpDown1.Location = new System.Drawing.Point(123, 47);
        this.numericUpDown1.Name = "numericUpDown1";
        this.numericUpDown1.Size = new System.Drawing.Size(120, 20);
        this.numericUpDown1.TabIndex = 1;
        this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged);
        // 
        // button2
        // 
        this.button2.Location = new System.Drawing.Point(155, 93);
        this.button2.Name = "button2";
        this.button2.Size = new System.Drawing.Size(75, 23);
        this.button2.TabIndex = 2;
        this.button2.Text = "button2";
        this.button2.UseVisualStyleBackColor = true;
        this.button2.Click += new System.EventHandler(this.button2_Click);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 262);
        this.Controls.Add(this.button2);
        this.Controls.Add(this.numericUpDown1);
        this.Controls.Add(this.button1);
        this.Name = "Form1";
        this.Text = "Form1";
        ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.Button button1;
    private System.Windows.Forms.NumericUpDown numericUpDown1;
    private System.Windows.Forms.Button button2;
}
Stefan
  • 115
  • 1
  • 15
  • 1
    Not a wise move to recall InitializeComponent. Did you get any exceptions? Please post that method (or at least the parts relative to the code above) – Steve Nov 30 '17 at 11:01
  • What is in your `InitializeComponent()`? You probably recreate all objets. not only assign events. – Pablo notPicasso Nov 30 '17 at 11:02
  • Sometimes when you do strange things like recalling `InitializeComponent()` your issue is already somewhere else or just the idea how you want to do something. – L. Guthardt Nov 30 '17 at 11:02
  • added my Code from the designer file – Stefan Nov 30 '17 at 11:03
  • InitialiceComponent isn't supposed to be called more than once and is **not** going to solve anything for you, more likely it will cause a whole host of new problems instead. Whatever you do you're going to find a different solution. – Lasse V. Karlsen Nov 30 '17 at 11:09
  • The issue is that once you recall `InitializeComponent()` you initialize every single component the second time which throws for 100% an execption, since all those controls got already initialised and you create them the second time with the same names, etc... . `InitializeComponent` is not meant to be called a second time. I think your issue is something else, a mindset that you think you have to go this way. Why do you need to use: `numericUpDown1.ValueChanged -= numericUpDown1_ValueChanged;` and why dont you wanna go with: `numericUpDown1.ValueChanged += numericUpDown1_ValueChanged;` ? – L. Guthardt Nov 30 '17 at 11:09
  • You should do it using `numericUpDown1.ValueChanged += numericUpDown1_ValueChanged;`. If you can't, or won't, you need to tell us why, perhaps there is a different problem we can help you solve. Another solution would be not to muck around with the events at all and instead just have a `bool` variable that is checked internally in the event handler to see if the *functionality* of the event should be enabled or not, even if the event handler is *called*. – Lasse V. Karlsen Nov 30 '17 at 11:26
  • @Steve posted a good solution for my problem. – Stefan Nov 30 '17 at 12:38

1 Answers1

-1

It is not correct to call a second time InitializeComponent. While it works, if not handled correctly, it creates a lot of bugs in your program.

When you call a second time InitializeComponent you ADD another numericUpdown control instance as well a second instance of every UI element in your form.
These second instances are placed in same exact position of the first instances but they are under (on the Z order) the first instances.
The control variables (numericUpDown1, button1, button2) now reference these new instances instead of the original ones.

The second instance of the numericUpDown gets the event handler assigned.
But you can't click it because it is under the first one which has the event handler still disabled.

If you want to call InitializeComponent a second time you need to massively edit it or first remove everything from the controls collection of your form and after all this there are good chances to screw everything.

For the first option you could have a perfomance hit (creation of the controls is not free), for the second one you can see by yourself the designer's code comment that reminds you how bad things could happen if you try to edit or mess with this function.

To prove it just change your button2 click handler to

private void button2_Click(object sender, EventArgs e)
{
    InitializeComponent();

    // Show the problem with a second call to InitializeComponent
    // The UD control moved is the second one with its handler active.
    numericUpDown1.Location = new Point(0,0);
}

Now you can see the two numericUpDown controls and if you click on the one at the zero location you will see that it reacts to your clicks while the first one is still unresponsive.

The appropriate way to reassing an event handler after it has been removed is through to += operator. You can read this answer to discover if the event handler has already been added

Steve
  • 213,761
  • 22
  • 232
  • 286
  • So someone downvoted without leaving a comment. Very useful for the future readers that will wonder what is wrong here. (me included) – Steve Dec 03 '17 at 16:22