winforms 在C#中单击鼠标三次?

mlnl4t2r  于 2023-05-23  发布在  C#
关注(0)|答案(6)|浏览(215)

MS-Word中,鼠标单击事件用作:
单击-放置光标
双击-选择单词
三次单击-选择段落
在C#中,我可以处理鼠标单击和双击事件,但我想在C# Windows TextBox中处理Triple Mouse Click事件。
示例:

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

ztmd8pv51#

看看这个Mousebuttoneventargs.clickcount
这应该包括它,我猜。

osh3o9ms

osh3o9ms2#

这样做:

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;
            };
        }
    }
l7wslrjt

l7wslrjt3#

你只需要存储时间,当一个双击发生在该框。然后,在单击的处理程序中,检查双击是否发生在不超过N毫秒之前(N = 300左右)。
在这种情况下,直接调用TripleClick()函数或为派生的“TripleClickAwareTextBox”定义一个新事件。

kwvwclae

kwvwclae4#

我在C++上也做过类似的工作
首先,你需要了解事件是如何触发的,我将使用鼠标左键单击:- 单击一次->左键单击事件触发-双击->左键双击事件触发
Windows仅支持您达到此级别。
对于三次点击,它基本上是一个点击后,双击与中间的时间足够小。因此,您需要做的是处理一个单击事件,检查在此之前是否有双击,并触发一个三次单击事件。
虽然代码不同,但我是这样做的:

  • 声明doubleClickTime & doubleClickInterval来存储上次双击的时间和两次点击之间的时间。
  • 声明tripleClickEventFired以指示我们已经触发了一个事件(init为false)
    • 处理程序**
  • 点击处理程序 *
if ((clock() - doubleClickFiredTime) < doubleClickInterval)
    <fire triple click event>
    tripleClickFired = true;
else
    <fire click event>
  • 双击处理程序 *
doubleClickTime == clock()
doubleClickInterval == GetDoubleClickTime() * CLOCKS_PER_SEC / 1000;

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

我使用的函数是:

  • clock():获取当前系统时间,单位为UNIT
  • getDoubleClickTime():Windows提供的一个函数,用于获取单击之间的时间间隔
  • "* CLOCKS_PER_SEC/1000;"part的目的是将GetDoubleClickTime()的返回值转换为UNIT""
    • 注意:**第三次单击会在系统级别触发单击和双击事件
ejk8hzay

ejk8hzay5#

我采用了Jimmy T的答案,将代码封装到一个类中,使其更容易应用于窗体上的多个控件。
这个类是这样的:

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;
                };
            }
        }
    }

然后,要将其应用于文本框,您可以这样做:

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

或者,如果您不使用控件的标记,则可以简单地执行以下操作:

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

bnl4lu3b6#

我扩展了Jimmy T的答案,并引入了逻辑,这样3次点击将选择单行/段落(在最近的2个回车之间),而4次点击将选择整个文本:

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;
        };
    }
}

相关问题