Click here to Skip to main content
15,891,730 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
I'm having trouble distinguishing single-click and double-click, and each click should do something different. What I mean is that the singleclick should detect if the value is selected and if not write a MessageBox. Double-clicking should have the function of disabling the Add-In.

What I have tried:

So I decided to write it like this:
C#
private bool click = false;
        private DateTime firstClick;
        private int clickCounter = 0;
        private double time;
        private DateTime secondClick;
 private void DoubleClick()
        {
            if (clickCounter == 2 && time < 1000)
            {
                FrameworkApplication.SetCurrentToolAsync(null);
                time = 0;
            }
        }
protected override void OnToolMouseDown(MapViewMouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
                e.Handled = true;
        }
 protected async override void OnToolMouseUp(MapViewMouseButtonEventArgs e)
        {
            await QueuedTask.Run(() =>
            {
                if (click == false)
                {
                    click = true;
                    firstClick = DateTime.Now;
                    clickCounter = 0;
                }
                else
                {
                    click = false;
                   secondClick=DateTime.Now;
                    time = (secondClick - firstClick).TotalMilliseconds;
                }
                if (shape == null)
                {
                    clickCounter++;
                    DoubleClick();
                    if (time > 1000)
                    {
                        time = 0;
                        click = false;
                        MessageBox.Show("Nothing!");
                    }
                    return;
                }
...

But I have a problem with the fact that if I click once and shape=null nothing happens at all, if I click a second time after a long time, it happens that the MessageBox runs, which would be fine, as well as if I double-click immediately, but when I double-click after some time from the first click, the order from the first click double-click is reversed to the second click double-click.

I hope it's understandable, but I don't really know how he explained it, due to the language barrier.

Thanks for the advice and help.

David
Posted
Updated 25-Jul-22 20:05pm
Comments
0x01AA 25-Jul-22 9:05am    
I assume it is WinForm and if it is: Is there a specific reason why you don't use the Click and DoubleClick events supported by the controls?
dejf111 26-Jul-22 1:17am    
Because if I choose DoubleClick, it interrupts the MessageBox in SingleClick...

Why not just capture the two events: Control.MouseClick Event (System.Windows.Forms) | Microsoft Docs[^] and Control.MouseDoubleClick Event (System.Windows.Forms) | Microsoft Docs[^] ? You just need some logic to check if the click comes immediately before the double click.
 
Share this answer
 
Comments
0x01AA 25-Jul-22 9:38am    
+5. In case controls are involved, the only correct approach. And one does even not need a logic ... if I remember correctly one will not get a Click event when it is a DoubleClick.
Richard MacCutchan 25-Jul-22 9:54am    
According to the documentation you will; but I have not tested it.
0x01AA 25-Jul-22 9:58am    
Just tested it. You are rigth, a Click comes also before DoubleClick.
Richard MacCutchan 25-Jul-22 10:04am    
What control did you test it on?
0x01AA 25-Jul-22 10:06am    
With a Panel. But yes, good point, other controls might behave differently.
[Edit]
I think the behaviour can be controlled maybe by ControlStyles.StandardDoubleClick and ControlStyles.StandardClick, but I'm too lazy to check that ;)
4 observations:
1) Don't use Task for this purpose. They add overhead and consume unneeded resources. Moreover, they are inherently "lazy", meaning you don't know exactly how much time passes between task invocation and task run.
2) In order to detect a multi-click (double, triple, etc..) you only need to know how much time has passed from the previous click.
3) Don't use DateTime to measure small times. Use Stopwatch or system ticks.

I'd use a parallel thread or an UI timer to monitor a couple of variables, where I'd store the timestamp of the last click and how many clicks have been performed within a maximum time frame from the first one.

The following is a quick-and-dirty example of the concept:
You have to address concurrency, instantiate/start the timer, and adapt it to your needs. You probably need to replicate the logic (partial code) of OnToolMouseUp to OnToolMouseDown.
You might also want to test for a maximum time in-between ticks (not only between the first and the last) and parametrize everything.

int ClickCountSoFar;
long LastClickTime;
long MaxTimeToMultiClick = Stopwatch.Frequency / 100; // 10 milliseconds

void RaiseClickEvent(int clickCount)
{
    if (clickCount == 1)
        RaiseSingleClick();
    else if (clickCount == 2)
        RaiseDoubleClick();
    else if (clickCount == 3)
        RaiseTripleClick();
}

void OnToolMouseUp(..)
{
    var now = Stopwatch.GetTimestamp();
    if (now - LastClickTime <= MaxTimeToMultiClick)
        ClickCountSoFar++;
    else
        ClickCountSoFar = 1;
    LastClickTime = now;
}


void OnTimer(..)
{
    var now = Stopwatch.GetTimestamp();
    if (ClickCountSoFar > 0 && now - LastClickTime > MaxTimeToMultiClick)
    {
        RaiseClickEvent(ClickCountSoFar);
        ClickCountSoFar = 0;
        LastClickTime = 0;
    }
}
 
Share this answer
 
v3
Your problems started when you decided to use a mouse click to "determine if something is selected".

A click is used to "select", or deselect a selected item, that is "selectable".

The way you've described it, you're better off with a "mouse over" event if you want to interrogate something (via a tooltip, for example).
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900