void init(){
control.MouseClick.Add(clickHandler);
}
void clickHandler(object sender, EventArgs e)
{
// Click logic
}
Now let see simple drag handler:
Point lastPos = null;
void init(){
control.MouseMove.Add(moveHandler);
}
void moveHandler(object sender, MouseEventArgs e)
{
if (lastPos == null)
lastPos = e.Location;
if (e.Button.HasFlag(MouseButtons.Left))
{
Point change = (e.Location - lastPos);
// Drag logic
}
lastPos = e.Location;
}
There is no need to handle the situations when mouse leaves or enters control's area because once mouse is pressed over some control, only that control will receive mouse related events. That greatly simplifies the code for handling the mouse movement. Only overhead is checking if last position has been initialized. I hope it work the same on Linux and Mac OS with Mono.
If those two pieces of code were combined, mouse drag that ends inside starting control will trigger click handler. One solution is to simply track how far was mouse dragged:
Point? lastPos = null;
double dragDist = 0;
void init(){
control.MouseClick.Add(clickHandler);
control.MouseMove.Add(moveHandler);
}
void clickHandler(object sender, EventArgs e)
{
if (dragDist > 0)
return;
// Click logic
}
void moveHandler(object sender, MouseEventArgs e)
{
if (!lastPos.HasValue)
lastPos = e.Location;
if (e.Button.HasFlag(MouseButtons.Left))
{
Point change = (e.Location - (Size)lastPos.Value);
dragDist += Math.Abs(change.X)
// Drag logic
}
else
dragDist = 0;
lastPos = e.Location;
}
Well, Euclidean distance would do too. I used Manhattan distance because the line of code is narrower and has less chance of being broken to multiple lines in your browser. Neat thing about this solutions is that border between click and drag can be adjusted to tolerate some mouse movement.