I was recently implementing some right-click functionality for a
TreeView, and I got to thinking, how many times have I handled the
MouseUp event and tested for
Buttons.Right because there isn't a
RightClick event in the
Control class? So I've written a mouse event helper class that lets you connect directly to these specific events:
public event EventHandler LeftClick;
public event EventHandler LeftDoubleClick;
public event EventHandler MiddleDoubleClick;
public event EventHandler RightDoubleClick;
public event EventHandler MiddleClick;
public event EventHandler RightClick;
public event MouseEventHandler LeftMouseDown;
public event MouseEventHandler LeftMouseUp;
public event MouseEventHandler MiddleMouseDown;
public event MouseEventHandler MiddleMouseUp;
public event MouseEventHandler RightMouseDown;
public event MouseEventHandler RightMouseUp;
public event MouseEventHandler WheelForward;
public event MouseEventHandler WheelBackward;
The implementation is trivial. The
MouseHelper class hooks the following control events:
protected virtual void Initialize()
A typical handler looks like this:
private void OnClick(object sender, EventArgs e)
if (LeftClick != null)
if (MiddleClick != null)
if (RightClick != null)
You will note that this isn't intended to handle situations where more than one mouse button is being held down at a time.
One thing that's odd is that, for wheel movement, the documentation says that:
A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, towards the user.
However, if I push the wheel away from me, what I think would mean forward, the program actually says I'm moving the wheel backwards.
To use the
- Instantiate the class and pass into the constructor the control for which you wish to trap mouse events.
- Assign the control to the
- Use the
You can add more than one control to the same mouse helper, which lets you combine mouse events from different controls into a single handler.
You should note that in the typical usage, you would use a unique
MouseHelper instance for every
Control class that you need to capture mouse events for. This is a drawback, but I wanted to keep the class simple. An alternative would be to have a static factory method that returns a
MouseHandler instance for the specific control you want to extend. And possibly, an even more interesting implementation would be to have
IExtenderProvider. Those may be future additions.
That's it! It's really simple, and now I have a helper class that takes care of the drudgery of writing over and over again the same "is the right button clicked" code. And my other motivation for writing this is because there was no way to handle right clicks declaratively. For example, I'd like to do something like this:
without writing a custom handler. Now I can!