Click here to Skip to main content
15,867,756 members
Articles / Programming Languages / C#

How to Change Event Handlers at Run Time

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
31 Oct 2011CPOL2 min read 5.4K   1   2
How to change event handlers at run time

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.

  1. User selects Music category from category combobox.
  2. User selects "Abby Road" from objects combobox.
  3. A list of album information is shown to him.

Here's the source:

C#
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:

C#
_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:

C#
_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:

C#
private EventHandler _nestedSelectedItemChangedEventHandler

Then I have this general event handler for the actual event:

C#
_itemComboBox.SeletedItemChanged+=
  GeneralItemChangedEventHandler;

When the category is changed, I place a new delegate in my nested event handler like this:

C#
_nestedSelectedItemChangedEventHandler=
_registeredEventHandlers[_selectedCategory.Type];

and GeneralItemChangedEventHandler will call nested event handler as follows:

C#
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow do your code snippets reflect reality ? Pin
MicroImaging31-Oct-11 8:44
MicroImaging31-Oct-11 8:44 
AnswerRe: How do your code snippets reflect reality ? Pin
RK KL18-Nov-11 4:20
RK KL18-Nov-11 4:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.