【C#】トリプルクリック以上の実装方法について考える

この記事は約5分で読めます。

だいたいのエディタだと下記みたいになっていますよね。自作エディタにもトリプルクリック以上の処理を追加しようと思っています。

  1. シングルクリックすると選択した位置にキャレットが移動する
  2. ダブルクリックすると単語選択する
  3. トリプルクリックすると行選択する
  4. クアドラプルクリックすると全行選択する

※4回クリックはクアドラプルクリックって言うらしいです。

現状のシングルクリックとダブルクリック処理

自作テキストエディタはシングルクリックとダブルクリックは MouseDownイベントで処理しています。ダブルクリックは MouseDoubleClick イベントでもいいでんすが、なぜか遅くないですかこのイベント?なんででしょうね。体感できるほど遅いので MouseDown イベントの e.Clicks プロパティが 2 ならダブルクリックとして処理しています。

トリプルクリックの時には MouseDown イベントで e.Clicks プロパティに 3 が設定されてくると思ってたんですがそんなことはなく 2 までしかこないんですよね。じゃーどーすんのって調べたら、特定時間内にクリックした回数に応じた処理にするようです。

サンプルソース

フォームにTextBoxコンポーネントとTimerコンポーネントを貼り付けてください。今回のケースではクリックしたタイミングで時間を計測してダブルクリックを認識する時間内にクリックした回数で処理を分けています。

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace Test {
    public partial class TripleClick : Form {

        private int clickInterval = 0;
        private int clickCnt = 0;
        private bool isFirstClick = true;

        public TripleClick() {
            InitializeComponent();
        }

        private void TripleClick_MouseDown(object sender, MouseEventArgs e) {
            // 計測開始
            if (this.isFirstClick) {
                this.isFirstClick = false;
                this.timer1.Start();
            }
            // クリック数カウント
            this.clickCnt++;

            // ダブルクリック間隔の時間を超えるまで処理
            if (this.clickInterval < SystemInformation.DoubleClickTime) {
                if (this.clickCnt == 1) {
                    Debug.WriteLine("キャレットの移動");
                    this.textBox1.SelectionStart = 6;
                    this.textBox1.SelectionLength = 0;
                } else if (this.clickCnt == 2) {
                    Debug.WriteLine("単語選択");
                    this.textBox1.SelectionStart = 6;
                    this.textBox1.SelectionLength = 6;
                } else if (this.clickCnt == 3) {
                    Debug.WriteLine("行選択");
                    this.textBox1.SelectionStart = 0;
                    this.textBox1.SelectionLength = 14;
                } else if (this.clickCnt == 4) {
                    Debug.WriteLine("全行選択");
                    this.textBox1.SelectionStart = 0;
                    this.textBox1.SelectionLength = this.textBox1.TextLength-1;
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e) {
            // 時間計測
            this.clickInterval += this.timer1.Interval;
            // ダブルクリック間隔の時間を超えたらリセット
            if (SystemInformation.DoubleClickTime < this.clickInterval) {
                this.timer1.Stop();
                this.clickInterval = 0;
                this.isFirstClick = true;
                this.clickCnt = 0;
            }
        }
    }
}

実装例

サンプルはフォームをクリックした回数に応じてテキストボックスのテキストを選択するようにしました。これまたわかりにくいですね。

処理の流れ

  1. シングルクリックで1行目のSystemの前にキャレットを移動します。
  2. ダブルクリックでSystemを選択します。
  3. トリプルクリックで1行目を選択します。
  4. クアドラプルクリックで全行選択します。

おわりに

フレームワークで判断可能にしてくれるといいんですけどね。

コメント

タイトルとURLをコピーしました