1

I have a form with the NumericUpDown and the ToolStripButton.

In the NumericUpDowns ValueChanged event handler the value of some object instance is changed.

In the ToolStripButtons Click event handler the object instance is saved.

Now the problem is that if I rewrite the value in the NumericUpDown and then click on the ToolStripButton to save the state the ToolStripButtons Click event is fired before the NumericUpDowns ValueChanged event so I first save the instance and after that I changed it.

public partial class Form2 : Form
{
    private Foo _foo = new Foo();

    public Form2()
    {
        InitializeComponent();
    }

    private void NumericUpDown1_ValueChanged(object sender, EventArgs e)
    {
        _foo.Value = numericUpDown1.Value;
    }

    private void ToolStripButton1_Click(object sender, EventArgs e)
    {
        _foo.Save();
    }

    private class Foo
    {
        public decimal Value { get; set; }

        public void Save()
        {
            //Save the value...
        }
    }
}

What is the best way to solve this?
Those events are fired in the correct order if I use the Button control, but not if I use the ToolStripButton control.

Artholl
  • 1,291
  • 1
  • 19
  • 38
  • 1
    Overload `Foo.Save()`, so it accepts a decimal argument: `Foo.Save(decimal value);`. The original, parameter-less, `Foo.Save()` can just call `Save(this.Value)`. In `ToolStripButton1_Click` you can then call `Foo.Save(numericUpDown1.Value)`, so it will save the current, manually edited, value. – Jimi May 29 '19 at 13:07
  • Well that is really interesting. So if I use the `numericUpDown1.Value` it will *refresh* its value and also immediately fires `ValueChanged` event so just after getting the `numericUpDown1.Value` I can also get the correct value from the `_foo.Value`. – Artholl May 29 '19 at 13:29
  • Yes. Fetching the current value, the sequence of events will revert to standard behaviour, so `ValueChanged` is raised right after you get the edited value. – Jimi May 29 '19 at 13:45

1 Answers1

1

As an option, instead of ValueChanged, handle Validated event of NumericUpDown and also in the Click event handler of ToolStripButton, call this.Validate() before save:

private void NumericUpDown1_Validated(object sender, EventArgs e)
{
    _foo.Value = numericUpDown1.Value;
}

private void ToolStripButton1_Click(object sender, EventArgs e)
{
    this.Validate();
    _foo.Save();
}

Note: If there are other controls on the form which may have Validating event and you may set e.Cancel = true for them, you need to check the result of Validate method before calling Save, using if(this.Validate()){ /*...*/ }.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • This solution works. I already tried to call `Validate`, but only for `NumericUpDown` and it didn't work. Any idea why it works for the whole `Form`, but not for the specified control? – Artholl May 30 '19 at 07:09
  • @Artholl My expectation is by calling `Validate` method of the `NumericUpdown` and handling `Validated` event, you get the same result; But I haven't tried that. – Reza Aghaei May 31 '19 at 10:22