How can I catch both single-click and double-click events on WPF FrameworkElement?

30,504

Solution 1

You need to fire the event after the click sequence is over... when is that? I suggest using a timer. The MouseDown event would reset it and increase the click count. When timer interval elapses it makes the call to evaluate the click count.

    private System.Timers.Timer ClickTimer;
    private int ClickCounter;

    public MyView()
    {
        ClickTimer = new Timer(300);
        ClickTimer.Elapsed += new ElapsedEventHandler(EvaluateClicks);
        InitializeComponent();
    }

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        ClickTimer.Stop();
        ClickCounter++;
        ClickTimer.Start();
    }

    private void EvaluateClicks(object source, ElapsedEventArgs e)
    {
        ClickTimer.Stop();
        // Evaluate ClickCounter here
        ClickCounter = 0;
    }

Cheers!

Solution 2

If you need to detect the difference, I suggest you use a control such as Label that does the work for you:

label.MouseDown += delegate(object sender, MouseEventArgs e)
{
    if (e.ClickCount == 1)
    {
        // single click
    }
};

label.MouseDoubleClick += delegate
{
    // double click
};

EDIT: My advice was following from documentation on MSDN:

The Control class defines the PreviewMouseDoubleClick and MouseDoubleClick events, but not corresponding single-click events. To see if the user has clicked the control once, handle the MouseDown event (or one of its counterparts) and check whether the ClickCount property value is 1.

However, doing so will give you a single click notification even if the user single clicks.

Solution 3

You must use a timer to differentiate between the two. Add a timer to your form in the GUI (easiest that way - it will automatically handle disposing etc...). In my example, the timer is called clickTimer.

private bool mSingleClick;

private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e)
{

    if (e.Button == MouseButtons.Left)
    {
        if (e.ClickCount < 2)
        {
            mSingleClick = true;
            clickTimer.Interval = System.Windows.Forms.SystemInformation.DoubleClickTime;
            clickTimer.Start();
        }
        else if (e.ClickCount == 2)
        {
            clickTimer.Stop();
            mSingleClick = false;
            MessageBox.Show("you double-clicked");
        }
    }
}

private void clickTimer_Tick(object sender, EventArgs e)
{
    if (mSingleClick)
    {
        clickTimer.Stop();
        mSingleClick = false;
        MessageBox.Show("you single-clicked");
    }
}

Solution 4

I did it this Way and it works perfectly

If e.Clicks = 2 Then
            doubleClickTimer.Stop()
        ElseIf e.Clicks = 1 Then
            doubleClickTimer.Enabled = True
            doubleClickTimer.Interval = 1000
            doubleClickTimer.Start()


        End If


 Private Sub doubleClickTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles doubleClickTimer.Tick

        OpenWebPage("abc")
        doubleClickTimer.Stop()
    End Sub

Solution 5

You are simply can use MouseDown event and count click number, like this:

if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2)
{
    // your code here
}
Share:
30,504
Angry Dan
Author by

Angry Dan

web/software developer, .NET, C#, WPF, PHP, software trainer, English teacher, have philosophy degree, love languages, run marathons my tweets: http://www.twitter.com/edward_tanguay my runs: http://www.tanguay.info/run my code: http://www.tanguay.info/web my publications: PHP 5.3 training video (8 hours, video2brain) my projects: http://www.tanguay.info

Updated on July 09, 2022

Comments

  • Angry Dan
    Angry Dan almost 2 years

    I can catch a single-click on a TextBlock like this:

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("you single-clicked");
    }
    

    I can catch a double-click on a TextBlock like this:

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            if (e.ClickCount == 2)
            {
                MessageBox.Show("you double-clicked");
            }
        }
    }
    

    But how do I catch them both on a single TextBlock and differentiate between the two?

  • Angry Dan
    Angry Dan over 14 years
    +1 for suggestion to use label, didn't realize it inherited from Control unlike TextBlock, but actually in my application I am receiving a FrameworkElement so I need some solution without using Control.
  • Patrick Klug
    Patrick Klug about 13 years
    "However, doing so will give you a single click notification even if the user single clicks." - you mean it gives you a single click even if the user double clicks, right?
  • Ed S.
    Ed S. about 13 years
    This doesn't work at all. You will still get MouseDown upon a double click and e.ClickCount will equal 1.
  • Natxo
    Natxo over 10 years
    @kelton52, i tried to show how it works. Use 'MouseLeftButtonDown' event or any other that fits your needs.
  • JayChase
    JayChase over 8 years
    This MSDN code sample shows how to create an attached behaviour which will run a double click command if the element is clicked twice within the system double click time or a single click command if not.
  • rollsch
    rollsch over 6 years
    Much simpler than the other answers.
  • mike
    mike about 4 years
    ...but doesn't help, if you need to differentiate between single & double click, i.e. handle a double-click only, if it actually was one, and a single-click only, if it actually was one...
  • mike
    mike about 4 years
    ...but that doesn't help, if you need to differentiate between single & double click, i.e. handle a double-click only, if it actually was one, and a single-click only, if it actually was one...