Michael Michael - 10 months ago 118
C# Question

Update Value of the NumericUpDown control without raising of ValueChanged event (Winforms)

I need to update a Value of the NumericUpDown control without raising of ValueChanged event (WinForms, C#).

The simple way is to remove event handler like:

numericUpDown.ValueChanged -= numericUpDown_ValueChanged;

After that to set the needed value:

numericUpDown.Value = 15;

And to add the event handler again:

numericUpDown.ValueChanged += numericUpDown_ValueChanged;

The problem is that I want to wright method that will get the NumericUpDown control as a first parameter, needed value as a second parameter and will update the value in the way that was given below.

To do it, I need to find the connected event handler for the ValueChanged event (for each NumericUpDown it's different).

I searched a lot, but didn't find the solution that would work for me.

My last try was:

private void NumericUpDownSetValueWithoutValueChangedEvent(NumericUpDown control, decimal value)
EventHandlerList events = (EventHandlerList)typeof(Component).GetField("events", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).GetValue(control);
object current = events.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField)[0].GetValue(events);
List<Delegate> delegates = new List<Delegate>();
while (current != null)
delegates.Add((Delegate)GetField(current, "handler"));
current = GetField(current, "next");
foreach (Delegate d in delegates)
public static object GetField(object listItem, string fieldName)
return listItem.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField).GetValue(listItem);

After running of NumericUpDownSetValueWithoutValueChangedEvent function, the
object current
is equal to null, so no one EventHandler was not found (I tried it on the Form - all event handlers were found).


Have you tried changing just the internal value and updating the text instead? That way you can bypass the eventhandler being fired.

If you take a look at the source code ( http://referencesource.microsoft.com/System.Windows.Forms/winforms/Managed/System/WinForms/NumericUpDown.cs.html#0aaedcc47a6cf725 ) You will see that the property Value is using a private field called currentValue this is the value you would like to set. And afterwards just do control.Text = value.ToString();


private void SetNumericUpDownValue(NumericUpDown control, decimal value)
    if (control == null) throw new ArgumentNullException(nameof(control));
    var currentValueField = control.GetType().GetField("currentValue", BindingFlags.Instance | BindingFlags.NonPublic);
    if (currentValueField != null)
        currentValueField.SetValue(control, value);
        control.Text = value.ToString();

This hasnt been tested but I'm pretty sure it will work. :) Happy coding!