Archives / 2007 / December
  • EventFilter Helper Class

    EventFilter is a generic helper class for dealing with events that may be raised multiple times in rapid succession, when only the last event of a “burst” is of interest.



    Imagine a Windows Forms program mimicking the GUI of the Windows Explorer, where selecting a folder in the tree view on the left side will update the list of files on the right. A "quick'n dirty" implementation would handle the SelectedNodeChanged event of the TreeView control to update the file list, but a robust implementation that works nicely with slow media like CD/DVD or network drives should use a different approach.

    When playing around with an actual instance of Windows Explorer and watching it more closely, you'll quickly notice that the file list is not updated immediately, but after a slight delay. You can use the keyboard in the tree view to move quickly from folder to folder, skipping folders you are not interested in. Only after you stay on a folder for a little while, the file list gets updated.

    This approach of "wait until things have settled down a bit and then handle the last occurrence of an event" is pretty common in GUI development. The typical implementation uses a timer that is reset each time a new event is raised within a certain time interval, until the timer is finally allowed to elapse. Only at that time the event will actually be handled.

    During development of a small hobby project called RemoteCanvas I got tired of taking care of timers, helper variables and event handlers over and over again, so I finally wrote a helper class acting as a "filter" for events.


    • Declare a member variable to hold an instance of the EventFilter class, with an event argument type matching that of the event to be filtered:
      private EventFilter<EventArgs> _filter
          = new EventFilter<EventArgs>();.
    • Hook up the HandleOriginalEvent method to the original event of the control. There's no great design time support for this, so you have to do that manually, e.g.
      myControl.SelectedIndexChanged += _filter.HandleOriginalEvent;
    • Connect the FilteredEventRaised event to your event handler:
      _filter.FilteredEventRaised += MyHandler;
    • That's it!


    The source code for the helper class (plus a small demo project for Visual Studio 2005) can be downloaded here.