1

Under certain conditions I'd like to cancel the ValueChanged event of a NumericUpDown control in Winforms (e.g. when the value set in the control is too high in relation to another value in a TextBox).

However, the EventArgs passed as argument into the event handler for the NumericUpDown control doesn't offer anything like "Cancel", so how can I do it?

    private void nudMyControl_ValueChanged(object sender, EventArgs e)
    {
      // Do some stuff, but only if the value is within a certain range.
      // Otherwise, cancel without doing anything.
    }
Gorgsenegger
  • 7,356
  • 4
  • 51
  • 89
  • How about limiting the NumericUpDown range with `Minimum` and `Maximum` properties ? This way the framework will block an attempt to enter an invalid value. – wohlstad Apr 10 '22 at 11:20
  • Unfortunately that doesn't work for my case, as the value has to be calculated dynamically. – Gorgsenegger Apr 10 '22 at 12:17
  • What do you want to do if the “calculated” value is not correct? Do you want to clear the NUD? Set it to some default value? Or return it to the last valid value? In other words, if the “calculated” value in the NUD is not correct… what value do you want the NUD to revert to? – JohnG Apr 10 '22 at 18:12
  • You cannot cancel `Changed` event. The control raises `Changed` event after the [value is changed](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/NumericUpDown.cs,05e91d1da762a5c3). As an option that you have, is keeping track of changes in a [fixed size queue](https://stackoverflow.com/questions/5852863/fixed-size-queue-which-automatically-dequeues-old-values-upon-new-enques) and revert changes if your validation failed. – Reza Aghaei Apr 10 '22 at 19:42

1 Answers1

0

You probably can handle this situation by using Minimum & maximum Properties, yet there are some solutions.

One way to do it is by creating a custom control, although it is nasty in my idea.

    public partial class CustomNumericUpDown : NumericUpDown
{
    public CustomNumericUpDown()
    {
        InitializeComponent();
    }

    protected override void OnTextBoxKeyDown(object source, KeyEventArgs e)
    {
        if (MyCustomCondition())
        {
            e.Handled = true;
        }
        base.OnTextBoxKeyDown(source, e);
    }

    private bool MyCustomCondition()
    {
        var checkOut = false;

        //if (something == foo)
        //{
            checkOut = true;
        //}

        return checkOut;
    }
}

You also can do stuff for ValueChanged:

This is some dummy sample, yet you can change it in your way:

    public virtual decimal CurrentEditValue { get; internal set; } = 0M;

    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        if (decimal.TryParse(Text, out decimal v))
        {
            CurrentEditValue = v;
            OnValueChanged(e);
        }
    }

    protected override void OnValueChanged(EventArgs e)
    {
        // if(CurrentEditValue == foo) Do_stuff.
        base.OnValueChanged(e);
    }
Reza Heidari
  • 1,192
  • 2
  • 18
  • 23