One of the challenges when using event handlers at run time, in my opinion, is that we can't manage previously registered event handlers very easily. I mean we don't know who else is listening to the same event.
Suppose we have two combo boxes and a list box. We want to let the user select a category in the first combo box and select an object in the second combo box and see a list of related information of that object in the list box.
- User selects
Music
category from category
combobox
. - User selects "
Abby Road
" from objects combobox
. - A list of album information is shown to him.
Here's the source:
private void CategorySelected(object sender,EventArgs e)
{
if(
((Categroy)_categoryComboBox.SelectedItem).Type==
CategroyType.Music
)
{
_itemComboBox.DataSource=_application.GetMusicAlbums();
}
}
private void ItemSelected(object sender,EventArgs e)
{
if(_itemComboBox.SelectedItem is MusicAlbum)
{
_list.DataSource=
_application.
GetMusicAlbumAdditionalInfo
((MusicAlbum)_itemComboBox.SelectedItem);
}
}
Well it's working but it's not very nice. As you can see, we should write a lot of "if
" to handle different kinds of categories and objects.
OK we could change the event handler instead of using if
. Suppose that we have registered some event handlers in a dictionary
, then we can write:
_itemComboBox.SelectedItemChanged+=
_eventhandlersRegistry[selectedCategory.Type];
But we have a little problem: what if there's already a category selected? So we should first remove last SelectedItemChanged
event handler, then we have to write:
_itemComboBox.SelectedItemChanged-=
_lastSelectedItemChangedEventHandler
_itemComboBox.SelectedItemChanged+=
_eventhandlersRegistry[selectedCategory.Type];
_lastSelectedItemChangedEventHandler=
_eventhandlersRegistry[selectedCategory.Type];
To solve this kind of scenario, I recently use a solution that I'd like to share with you:
I use a nested EventHandler
delegate, therefore there's no need to change the event handler of actual event. Here's what I do: I have an event handler delegate declared as:
private EventHandler _nestedSelectedItemChangedEventHandler
Then I have this general event handler for the actual event:
_itemComboBox.SeletedItemChanged+=
GeneralItemChangedEventHandler;
When the category is changed, I place a new delegate in my nested event handler like this:
_nestedSelectedItemChangedEventHandler=
_registeredEventHandlers[_selectedCategory.Type];
and GeneralItemChangedEventHandler
will call nested event handler as follows:
private void GeneralItemChangedEventHandler (object sender,EventArgs e)
{
if(_nestedSelectedItemChangedEventHandler!=null)
_nestedSelectedItemChangedEventHandler(sender,e);
}
This approach can be used if you are implementing a strategy pattern so that you want to change the behavior by changing the state of your object and there's always a single event handler involved to handle an event.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.