Have you ever tried to override a event suscription in c#?
Let’s say you have a form with a control inherited from a button, and you want to INTERCEPT THE EVENT SUSCRIPTION.
For instance if you have a second button, you want that whenever somebody suscribes to the click event of this button, it also suscribes to the event click of another button or change the target event handler, or log it or whatever processing you can imagine.
In my example I’m going to use event suscription override to automatically use the event handler as the handler of the click of another button
That is, that writing this:
this.button1.Click += new System.EventHandler(this.button1_Click);
Is going to be implicitly equivalent to this:
this.button1.Click += new System.EventHandler(this.button1_Click);
this.button2.Click += new System.EventHandler(this.button1_Click);
and I’m going to do this through event overriding (Full test vs2005 project can be downloaded here )
As you probably know, this is not possible in c#
class InheritedButton : Button
{
// That's not allowed
public override Click ...
so we are going to use a little trick (including reflection) to simulate that.
First, I am going to define a new ‘EventHandler’ class that includes a virtual function to allow extension on inherited classes.
Things to note:
1. The constructor includes both the control and the event name you want to handle (so we can use in reflection)
2. The class defines a operator + to keep the common event suscription sintaxis
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
namespace TestOverrideEvent
{
// By Javier Alvarez de Pedro, if you use this code... well, I'm glad to help you :)
public class BaseOverrideEventHandler
{
private Control m_ctrl;
public Control Ctrl
{
get { return m_ctrl; }
set { m_ctrl = value; }
}
private String m_eventName;
public String EventName
{
get { return m_eventName; }
set { m_eventName = value; }
}
public BaseOverrideEventHandler(Control ctrl,string eventName)
{
m_ctrl = ctrl;
m_eventName = eventName;
}
public static BaseOverrideEventHandler operator +(BaseOverrideEventHandler pbEventhandler, EventHandler handler)
{
// Suscribe to event
string eventName = pbEventhandler.m_eventName;
Control ctrl = pbEventhandler.m_ctrl;
EventInfo ei = ctrl.GetType().GetEvent(eventName);
ei.AddEventHandler(pbEventhandler.m_ctrl, handler);
// Call for aditional operations on inherited classes
pbEventhandler.SuscribeTasks(pbEventhandler, handler);
// Return modified event handler
return pbEventhandler;
}
public static BaseOverrideEventHandler operator -(BaseOverrideEventHandler pbEventhandler, EventHandler handler)
{
// Suscribe to event
string eventName = pbEventhandler.m_eventName;
Control ctrl = pbEventhandler.m_ctrl;
EventInfo ei = ctrl.GetType().GetEvent(eventName);
ei.RemoveEventHandler(pbEventhandler.m_ctrl, handler);
// Return modified event handler
return pbEventhandler;
}
public virtual void SuscribeTasks(BaseOverrideEventHandler overrideEventHandler, EventHandler eventHandler)
{
}
}
}
Then I write a inherited class for customizing the event handling, so when you suscribe to the click event, you are also suscribing to the click of the rest of the buttons
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace TestOverrideEvent
{
// By Javier Alvarez de Pedro, if you use this code... well, I'm glad to help you :)
class MyOverrideEventHandler : BaseOverrideEventHandler
{
public MyOverrideEventHandler(Control ctrl)
: base(ctrl, "Click")
{
}
public override void SuscribeTasks(BaseOverrideEventHandler overrideEventHandler, EventHandler eventHandler)
{
base.SuscribeTasks(overrideEventHandler, eventHandler);
Control ctrl = overrideEventHandler.Ctrl;
foreach (Control c in ctrl.Parent.Controls)
{
if (c is Button && c != ctrl)
{
c.Click += eventHandler;
}
}
}
}
}
And then I create a button that ‘overrides ‘ the click event
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using TestOverrideEvent;
namespace TestOverrideEvent
{
class InheritedButton : Button
{
// That's not allowed
//public override Click ...
private BaseOverrideEventHandler m_Click;
public InheritedButton()
{
m_Click = new MyOverrideEventHandler(this);
}
public new BaseOverrideEventHandler Click
{
get
{
return m_Click;
}
set
{
m_Click = value;
}
}
}
If you just define a form with a Inherited button and a few other buttons, suscribe ONLY to the click of the button1 and … magic! When you click the other buttons, the event is also fired! (Note that I haven’t modified the sintaxis of the suscription, you keep using a System.EventHandler for suscribing)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace TestOverrideEvent
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.button1.Click += new System.EventHandler(this.button1_Click);
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Click 1");
}
}
}
4 comments:
splendid. thank you. hope this is the proper way to do it.
After checking out a handful of the blog posts on your website, I
truly like your technique of blogging. I added it to my bookmark website list and will be checking back soon.
Please visit my website as well and let me know how you feel.
Also visit my page direct deposit cash advances
My web page :: best payday loans
Great work! This is the type of information that are meant to be
shared across the internet. Disgrace on Google for not positioning this submit higher!
Come on over and visit my site . Thanks =)
Visit my web site: breast enhancement pill
buy ativan ativan 4 weeks pregnant - right dosage ativan
Post a Comment