How to 'copy' EventHandler

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hallo,
i would like to set some event handlers of new object to handlers assigned
with old one.... something like folowing:

MyControl ctr = new MyControl();
ctr.Click += myClickHandler;
MyControl newCtr = new MyControl();
newCtr = ctr.Click; // doesn't work

Is it possible somehow to assign one MulticastDelegate to another?
 
Hello, Michael!

Your click handler is myClickHandler. You must assign it to another control
Click event.
Your code must be as this:

MyControl ctr = new MyControl();
ctr.Click += myClickHandler;
MyControl newCtr = new MyControl();
newCtr.Click += myClickHandler;

Your handler'll handle both Click events.

Alexander.
 
To copy event from one control to another (with all handlers) use:

CopyEvent(ctr, newCtrl, "Clock");

....

private void CopyEvent(Control a, Control b, string commonField)
{
Type typeControl = typeof(Control);
FieldInfo fi = typeControl.GetField(commonField,
BindingFlags.NonPublic|BindingFlags.Instance);
Delegate source = fi.GetValue(a) as Delegate;

fi.SetValue(b, source);
}

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com
 
Hi Alexander,
the problem is that i do not have a clue what all handlers ware assigned to
that control. I am creating that new control in diferent code location and i
wont it to call all handlers assigned with the first one... better example
should be this code:

public MyForm()
{
MyControl ctr = new MyControl();
ctr.Click += myClickHandler;
....
ctrl.Click += commonClickHandler;
}

public MyControl
{
public static MyControl GetCashedControl(Control sender, string name)
{
MyControl ctr = FindChashedControl(name);
// copy some properties
...
// assign events
ctr.Click = sender.???
...

return ctr;
}
}
 
Hi, thanks for your reference, but i found problem when testing Sergey's and
your solutions...
When calling GetField or GetFields i cannot retrieve fields of base classes
of my type.
For example:

Type t = typeof(System.Windows.Forms.ComboBox);
foreach( FieldInfo f in
t.GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance))
{
Debug.WriteLine("field: "+f.Name);
}

Found fields:
m_objcol, SelectedIndexChanged, m_datasrc, m_bdginfoDisplay, m_bdginfoValue,
m_datamgr, m_fChangingSelection, m_hwn, m_wnt, m_thread, m_mnucOwned,
m_mnucFloating, m_qutaskInvoke, m_dataBindings, m_bindingContext,
m_fDisposed, m_fEnabledReal

Fields such as Click,Paint,Resize,Validated... are not returned untill i
call GetFields for typeof(Control)

I tryed to use BindingFlags.FlattenHierarchy but it flats only static
members...
 
Ok, here you are (slightly modified version). Briefly, it starts with
the current variable type and moves up hierarchy till your variable will
not be found or the end is reached.

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com
 
sorry

private void CopyEvent(Button a, Button b, string commonField)
{
FieldInfo fi = null;
Type typeControl = a.GetType();
while (typeControl != typeof(System.Object))
{
fi = typeControl.GetField(commonField,
BindingFlags.NonPublic|BindingFlags.Instance);
if (fi != null) break;

typeControl = typeControl.BaseType;
}

if (fi == null) new ArgumentException("commonField");

Delegate source = fi.GetValue(a) as Delegate;
fi.SetValue(b, source);
}

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com
 
Back
Top