Search code examples
c#winformseventscontrolsclone

How to clone value changed event from control at run time


I tried to clone the events from one NumericUpDown to another on. I found a solution that fits nearly all my needs her:

How to clone Control event handlers at run time?

Surprisingly, the ValueChanged - Event will not be cloned and I have no clue why.

Heres my code

        NumericUpDown numericUpDown2 = new NumericUpDown();

        FieldInfo eventsField = typeof(Component).GetField("events", BindingFlags.NonPublic | BindingFlags.Instance);
        var eventHandlerList = eventsField.GetValue(numericUpDown1);
        eventsField.SetValue(numericUpDown2, eventHandlerList);

        numericUpDown2.Location = new Point(100, 100);
        numericUpDown2.Name = "numericUpDown2";

        Controls.Add(numericUpDown2);

numericUpDown1 contains Events for ValueChanged, KeyDown, Validating, Validated, Enter, Leave and Click. For example:

private void numericUpDown1_Validating(object sender, CancelEventArgs e)
    {
        Debug.WriteLine("Validating " + ((Control)sender).Name);
    }

I write some debug infos to the output Window which shows following for numericUpDown1:

  • Validating numericUpDown2
  • Validated numericUpDown2
  • Enter numericUpDown1
  • Value changed numericUpDown1
  • Click numericUpDown1

And for numericUpDown2:

  • Validating numericUpDown1
  • Validated numericUpDown1
  • Enter numericUpDown2
  • Click numericUpDown2

Just the same without the value changed event. To make it work I have to add

numericUpDown2.ValueChanged += numericUpDown1_ValueChanged;

But this isn't the solution I'm searching for. I dont understand why the ValueChanged - Event is something special and not copied to. (I know that i only get a reference to the events and when I add/remove an event from one control the other is also affected, but this is exactly what i want)

btw... is numericUpDown the only control with ValueChanged - Event?

Thanks for help!


Solution

  • ValueChanged event of NumericUpDown uses a different pattern that common events. It stores in onValueChanged rather than an EventHandlerList:

    private EventHandler onValueChanged = null;
    public event EventHandler ValueChanged {
        add {
            onValueChanged += value;
        }
        remove {
            onValueChanged -= value;
        }
    }
    

    It basically means, copying the event EventHandlerList will not do the tick for you here.

    To see how to use event properties in controls, take a look at this document: