Javed Akram
Javed Akram

Reputation: 15344

Triple Mouse Click in C#?

In MS-Word Mouse Click events are used as:

Single Click - placing Cursor
Double Click - Selects Word
Triple Click - Selects Paragraph

In C# I can handle single and double mouse click events but I want to handle a Triple Mouse Click event in C# Windows TextBox.

Example:

void textbox1_TripleClick()
{
    MessageBox.Show("Triple Clicked"); 
} 

Upvotes: 10

Views: 6556

Answers (6)

E. Einbinder
E. Einbinder

Reputation: 1

I expanded on Jimmy T's answer, and introduced logic so that 3 clicks will select a single line/paragraph (between nearest 2 carriage returns), while 4 clicks will select the entire text:

private void txtTextMessage_MouseUp(object sender, MouseEventArgs e)
{
    _timer.Stop();
    _clicks++;
    if (_clicks == 4)
    {
        //Select the whole text
        txtTextMessage.SelectAll();
        _clicks = 0;
    }
    if (_clicks == 3)
    {
        //Select the current "paragraph"
        var currentCursorPosition = txtTextMessage.SelectionStart;
        var beginningOfParagraph = txtTextMessage.Text.LastIndexOf("\n", currentCursorPosition) + 1; //if not found, will be 0, which is start of string
        var endOfParagraph = txtTextMessage.Text.IndexOf("\r\n", currentCursorPosition); //first look for next CRLF
        if (endOfParagraph < 0)
        {
            endOfParagraph = txtTextMessage.Text.IndexOf("\n", currentCursorPosition); //if not found, look for next LF alone
            if (endOfParagraph < 0)
                endOfParagraph = txtTextMessage.Text.Length; //if still not found, use end of string
        }
        txtTextMessage.SelectionStart = beginningOfParagraph;
        txtTextMessage.SelectionLength = endOfParagraph - beginningOfParagraph;
    }
    if (_clicks < 4)
    {
        _timer.Interval = 500;
        _timer.Start();
        _timer.Tick += (s, t) =>
        {
            _timer.Stop();
            _clicks = 0;
        };
    }
}

Upvotes: 0

Adrian Bhagat
Adrian Bhagat

Reputation: 203

I have adapted Jimmy T's answer to encapsulate the code into a class and to make it easier to apply to multiple controls on a form.

The class is this:

    using System.Windows.Forms;

    public class TripleClickHandler
    {
        private int _clicks = 0;
        private readonly System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer();
        private readonly TextBox _textBox;
        private readonly ToolStripTextBox _toolStripTextBox;

        public TripleClickHandler(TextBox control)
        {
            _textBox = control;
            _textBox.MouseUp += TextBox_MouseUp;
        }
        public TripleClickHandler(ToolStripTextBox control)
        {
            _toolStripTextBox = control;
            _toolStripTextBox.MouseUp += TextBox_MouseUp;
        }
        private void TextBox_MouseUp(object sender, MouseEventArgs e)
        {
            _timer.Stop();
            _clicks++;
            if (_clicks == 3)
            {
                // this means the trip click happened - do something
                if(_textBox!=null)
                    _textBox.SelectAll();
                else if (_toolStripTextBox != null)
                    _toolStripTextBox.SelectAll();
                _clicks = 0;
            }
            if (_clicks < 3)
            {
                _timer.Interval = 500;
                _timer.Start();
                _timer.Tick += (s, t) =>
                {
                    _timer.Stop();
                    _clicks = 0;
                };
            }
        }
    }

Then, to apply it to a textbox you can do this:

partial class MyForm : Form
{
    UIHelper.TripleClickHandler handler;
    public MyForm()
    {
        InitializeComponent();
        handler = new UIHelper.TripleClickHandler(myTextBox);
    }
}

Or, if you aren't otherwise using the control's tag you can simply do this:

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
        myTextBox.Tag = new UIHelper.TripleClickHandler(myTextBox);
    }
}

Upvotes: 1

Jimmy T.
Jimmy T.

Reputation: 111

DO THIS:

    private int _clicks = 0;
    private System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer();
    private void txtTextMessage_MouseUp(object sender, MouseEventArgs e)
    {
        _timer.Stop();
        _clicks++;
        if (_clicks == 3)
        {
            // this means the trip click happened - do something
            txtTextMessage.SelectAll();
            _clicks = 0;
        }
        if (_clicks < 3)
        {
            _timer.Interval = 500;
            _timer.Start();
            _timer.Tick += (s, t) =>
            {
                _timer.Stop();
                _clicks = 0;
            };
        }
    }

Upvotes: 6

exklamationmark
exklamationmark

Reputation: 325

I was working on a similar issue on C++

Firstly, you need to understand how the events are fired, i 'll take click using the left mouse button: - Click once -> Left button click event fired - Double click -> Left double click event fired

Windows only support you up to this level.

For triple click, it's essentially a click following a double click with the in-between time small enough. So, what you need to do is handle a click event, check if there was a double click before that and fire a triple click event.

Though the code is different, this is how I do it:

  • Declare doubleClickTime & doubleClickInterval to store the last time we double click & the time between clicks.
  • Declare tripleClickEventFired to indicate we have already fired an event (init to false)

Handlers

Click Handler

if ((clock() - doubleClickFiredTime) < doubleClickInterval)
    <fire triple click event>
    tripleClickFired = true;
else
    <fire click event>

Double click handler

doubleClickTime == clock()
doubleClickInterval == GetDoubleClickTime() * CLOCKS_PER_SEC / 1000;

If ( !tripleClickEventFired)
    <fire doubleClickEvent>
else
    tripleClickEventFired = false;

The functions I use was:

  • clock(): get the current system time in UNIT
  • GetDoubleClickTime(): a function provided by Windows to get the time between clicks
  • the "* CLOCKS_PER_SEC / 1000;" part is meant to covert the return value of GetDoubleClickTime() to UNIT'''

NOTE: the 3rd click fires both a Click and Double Click event on system level

Upvotes: 2

Abuh
Abuh

Reputation: 461

Have a look at this: Mousebuttoneventargs.clickcount

That should cover it I suppose.

Upvotes: 8

TToni
TToni

Reputation: 9391

You just have to store the time when a double click occured in that Box. Then, in the handler for the single click, check if a double click happened not more than N milliseconds ago (N = 300 or so).

In this case, call your TripleClick() function directly or define a new event for you derived "TripleClickAwareTextBox".

Upvotes: 2

Related Questions