I have the following forms in my winforms framework
Now every form in the application inherits from on one of the 3 above.
For example FormCustomerList
will be inherited from FormBaseList
Now in FormBaseList
the event FormBaseList_Shown
is present (by doubleclicking on it in the properties window in VS)
What I would like to know in the code from FormBaseList_Show
is if there is an event FormCustomerList_Show
present (again by doubleclick on it in the properties window).
Is that even possible ?
So why do I want this ?
Because some changes in the framework require the forms to not use the Shown
event anymore but a custom event.
I would like to catch and show a warning to the developer if he adds a Show
event to a form, and if it is really needed he can set a property that will hide this warning.
This warning does not needs to be shown at designtime, at runtime would be enough. But if its possible at designtime that would be a bonus.
So can this be done and is there maybe a better way to do this ?
I hope this explanation is clear
EDIT
The idea is that when a developer makes use of a Show event he must get a warning (either at designtime or runtime). If he feels that he really needs the Show method he should be able to set the warning off for this particular form
To throw exception or show a message box at run-time you have the following options:
Shown
event and in the add
part, throw an exception (unless the skip flag has been set).Shown
event and check if there is a handler attached to the event.In both solutions, a boolean property can be used to override the behavior in derived forms.
Option 1 - Shadowing Shown event and add the code to add
You can shadow the Shown
event and in the add
accessor, add a code to show a message box or throw exception if a handler added to the event.
In the following example, I've added ThrowExceptionOnSubscribingShownEvent
property to the base form which is true
by default which means it throws the exception on subscribing the Shown
event.
public bool ThorwExceptionOnSubscribingShownEvent { get; set; } = true;
public new event EventHandler Shown
{
add
{
if (ThorwExceptionOnSubscribingShownEvent)
throw new InvalidOperationException("Shown event is deprecated.");
base.Shown += value;
}
remove
{
base.Shown -= value;
}
}
Option 2 - Finding event handler list for Shown
event
As an option for run-time, you can override OnShown
method and using reflection, get EVENT_SHOWN
field and using it, get the event handler list of Shown
event. Then you can check if the event handler list is not empty, throw an exception.
In the following example, I've added ThrowExceptionOnSubscribingShownEvent
property to the base form which is true
by default which means it throws the exception on subscribing the Shown
event. You can set it to false
when needed in derived forms:
public partial class BaseForm : Form
{
public BaseForm()
{
InitializeComponent();
}
public bool ThrowExceptionOnSubscribingShownEvent { get; set; } = true;
protected override void OnShown(EventArgs e)
{
if (!DesignMode)
{
var EVENT_SHOWN = typeof(Form).GetField("EVENT_SHOWN",
BindingFlags.NonPublic | BindingFlags.Static)
.GetValue(null);
var handlers = Events[EVENT_SHOWN]?.GetInvocationList();
if (ThrowExceptionOnSubscribingShownEvent && handlers?.Length > 0)
throw new InvalidOperationException("Shown event is deprecated.");
}
base.OnShown(e);
}
}