Mouse Events






4.66/5 (19 votes)
Jun 2, 2005
2 min read

175732

3260
A helper class to expand on the mouse events provided by the Control class.
Introduction
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;
Implementation
The implementation is trivial. The MouseHelper
class hooks the following control events:
protected virtual void Initialize()
{
control.Click+=new EventHandler(OnClick);
control.DoubleClick+=new EventHandler(OnDoubleClick);
control.MouseDown+=new MouseEventHandler(OnMouseDown);
control.MouseUp+=new MouseEventHandler(OnMouseUp);
control.MouseWheel+=new MouseEventHandler(OnMouseWheel);
}
A typical handler looks like this:
private void OnClick(object sender, EventArgs e)
{
switch(lastButton)
{
case MouseButtons.Left:
if (LeftClick != null)
{
LeftClick(sender, e);
}
break;
case MouseButtons.Middle:
if (MiddleClick != null)
{
MiddleClick(sender, e);
}
break;
case MouseButtons.Right:
if (RightClick != null)
{
RightClick(sender, e);
}
break;
}
}
You will note that this isn't intended to handle situations where more than one mouse button is being held down at a time.
Wheel Movement
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.
Usage
To use the MouseHelper
class:
- Instantiate the class and pass into the constructor the control for which you wish to trap mouse events.
- Assign the control to the
MouseHelper
'sControl
property. - Use the
MouseHelper
'sAddControl
method.
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 MouseHandler
implement IExtenderProvider
. Those may be future additions.
Conclusion
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:
<TreeView RightClick="PopupMenu"/>
without writing a custom handler. Now I can!