Reputation: 1333
I'm working on a project where I'm actually using inherited controls with some automated behaviour so I don't need to re-do all the job. The controls are being inherited from DevExpress controls and I've got access to the inherited controls.
I reached a point where an event was being raised and subscribing to my own method was showing no results because the inherited control executed its own code.
Inherited control:
private void BinaryGridView_InvalidRowException(object sender, InvalidRowExceptionEventArgs e)
{
e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction;
DevExpress.XtraEditors.XtraMessageBox.Show(e.ErrorText, "Atención", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Own method in my form:
grwWhatever.InvalidRowException += (s, e) => { e.ExceptionMode = ExceptionMode.NoAction; };
According to the documentation, I was trying to hide any message box and of course, as my inherited control source says, it was showing that message box.
So, reaching that point I guess had two options:
1.- Inheriting from that inherited control, changing the private
to protected virtual
and overriding that behaviour. This wasn't a choice since, for reasons I couldn't explain here I must use uniquely those inherited controls.
2.- Changing the private
to public
, so I could unsubscribe and subscribe again, afterwards:
grwWhatever.InvalidRowException -= grwWhatever.BinaryGridView_InvalidRowException;
grwWhatever.InvalidRowException += (s, e) => { e.ExceptionMode = ExceptionMode.NoAction; };
This 2nd option is actually working fine but... let's guess none of them are doable. Changing the content of the inherited control's event is not a possibility. Leaving a part the inherited control's usage design... Which would be the best way to proceed? Could it be done using Reflection
?
Upvotes: 1
Views: 539
Reputation: 125197
The right solution should be changing the code in the base class. But since you have mentioned you don't have access to change the code of base class, and a solution using reflection is also acceptable, here I will share an example using reflection, for learning purpose.
Remove private event handler subscription from base class
I assume I have a base class called MyBaseForm
and you have handled Load
event using MyBaseForm_Load
private method in the base class.
In this example, in a derived class MyDerivedForm
which is derived from base class, I use some reflection code to remove the MyBaseForm_Load
event subscription and instead, I handle the event using a new handler in the derived class MyDerivedForm_Load
.
The expected behavior:
eventInfo.RemoveEventHandler
, you will see just a single message box, from the derived class event handler.Here is the code:
public class MyBaseForm : Form
{
public MyBaseForm()
{
this.Load += MyBaseForm_Load;
}
private void MyBaseForm_Load(object sender, EventArgs e)
{
MessageBox.Show("MyBaseForm_Load");
}
}
public class MyDerivedForm : MyBaseForm
{
public MyDerivedForm()
{
var eventInfo = this.GetType().GetEvent("Load",
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance);
var delegateType = eventInfo.EventHandlerType;
eventInfo.RemoveEventHandler(this,
Delegate.CreateDelegate(delegateType, this, "MyBaseForm_Load", false, true));
this.Load += MyDerivedForm_Load;
}
private void MyDerivedForm_Load(object sender, EventArgs e)
{
MessageBox.Show("MyDerivedForm_Load");
}
}
Upvotes: 1