tags:

views:

997

answers:

4

I want to override OnMouseClick and OnMouseDoubleClick and perform different actions depending on which click style was used.

The problem is that OnMouseClick is happening for both single and double clicks, and is getting called before OnMouseDoubleClick.

I'm certain this must be a common requirement, so I guess I'm missing something pretty obvious. Can someone fill me in?

Edit to add: the MouseEventArgs.Clicks count doesn't help. In the case of a double-click, the first click is handled as a single click in OnMouseClick with MouseEventArgs.Clicks == 1.

Edit to add: the objects are image thumbnails. Single click should toggle selection on and off for export. Double click should make the thumbnail full screen. The selection and "activation" actions are orthogonal. This may indicate an underlying problem with the two actions...

Cheers, Rob

+8  A: 

That happens throughout Windows. I don't think they added anything special to handle it in .Net.

The normal means of handling this is

  • a) just make single click something you'd want to happen before a double click, like select.
  • b) if that's not an option, then on the click event, start a timer. On the timer tick, do the single click action. If the double-click event occurs first, kill the timer, and do the double click action.

The amount of time you set the time for should be equal to the system's Double-Click time (which the user can specify in the control panel). It's available from System.Windows.Forms.SystemInformation.DoubleClickTime. The full details are in the MSDN, here

James Curran
Remember when setting up your timer that people can and often DO screw around with their double-click settings: http://blogs.msdn.com/oldnewthing/archive/2008/10/02/8969396.aspx ... Be sure to accomodate that, otherwise you might still get single-clicks before doubles in certain weird cases.
John Rudy
A timer!? Nooooooo! (OK, I accept that it's practical, but it's not pretty. Is this really the only way?)Cheers,Rob
Rob
+ 1 to option a. option b can be done, but as John say, bad things can happen. In your scenario, it is safe to use first click = select, second click = fullscreen
mathieu
Single click must be both select and deselect. When changing to fullscreen, the user will not be expecting their selection to change.
Rob
So, you're saying a user would click item to select it, then double-click a different item to full-screen it, and expects the first item to remain selected?
James Curran
That would be entirely possible, yes. They may also click an item, then double click the same icon, and expect the selection state to remain unchanged.
Rob
that doesn't sound like a great design dude...
Nicholas Mancuso
@Nicholas - you might be right! Got any ideas for something better?
Rob
@mathieu, yes, bad things could happen, but if that is the UX needed, that is the way it's in done, in Windows core and in thousands of apps over the last 20 years.
James Curran
A: 

The issue is that most objects don't implement both. The few objects that can reasonably have different actions for single and double clicks generally are OK to run the single click action before the double click action (highlight then open a folder, enter focus on an address bar before selecting it, etc.) The only way to determine would probably be to wait on the single click for an amount of time and cancel the action for the single click if a double click is detected.

tloach
A: 

You could start a timer within the OnMouseClick event handler.

  • If the timer times out (say 300ms) then a single click is intended.

Else

  • If another OnMouseClick event was generated before the time times out you could examine the x&y position of the click and if its within a particular radius of the first click then action the double click functionality.

Otherwise

  • Handle first click and re-initialise timer for second click

NB: This implementation has the advantage of the fact that both the timeoput and the 'double-click' radius can be configured independantly of the system configuration allowing the s/w to be imported onto multiple machines/

TK
But has the disadvantage of ignoring the users' own double click timeout preferences!
Rob
This is true, but it means that you can create a consistent system that is user independant. I suppose it boils down to who uses the system, one user or multiple users.
TK
A: 

Another possible solution is to have the OnMouseDoubleClick function call OnMouseClick. Since the action in OnMouseClick is a binary toggle, calling it twice resets it to the same state.

So when the user double clicks, windows calls OnMouseClick, then OnMouseDoubleClick. OnMouseDoubleClick calls OnMouseClick (again) to restore the state, then handles the double click.

This feels unsatisfying as a solution, but it works.

Using a timer (to swallow the first click of the double click) is equally unsatisfying, and has the added complication of handling user's double click rate preferences.

Cheers, Rob

Rob
I'm not certain that even works. For example: User click A, then double-click B, which selects, deselects and expands B. Now, did selecting B, deselect A? If so, you're screwed.
James Curran
The objects are handled independently, so A is independent of B. In my implementation, the cursor position passed in via the MouseEventArgs is used to identify which image was clicked on.
Rob