[C#]TextBoxで、マウスクリック(1回目)だけ、内容を全選択させる

投稿日:2018-06-13

  • TextBoxの内容を全選択させるには、SelectAll()を使用
  • マウスの1回目も含めるなら、BeginInvoke~を使用

VB.net版はこちら。

TextBoxの中身を全選択させたい

テキスト入力エリアなら何でもいいんですが、例えば、InternetExplorerのアドレスバーを選択してみてください。

URLが全選択されるじゃないですか。

TextBoxでは、マウスクリック時には全選択されない

次に、Yahooの検索欄に適当に文字を入力して・・・

検索欄をクリックしても、全選択にはなりません。

Tab移動なら全選択になる

そうです、Tab移動なら全選択になります。

例示する画面を作るのが面倒くさかったので、IEで説明しましたが、TextBoxもこんな挙動してくれます。

入力ミスが多発する

システム画面の話に勝手に戻しますが、Tab移動という概念を持っていないお客さんって割りと入るんですよね。

そういったお客さんは、誠実にマウスでテキストボックスをクリックして入力してくれます。

で、その時何が起こるかというと・・・

入力ミス(ヒューマンエラーではないw)が発生します。

例えばですが、既に「10」とか入力されている数値を「15」に修正したいときに、マウスで選択して、入力を始めると・・・「1015」とか「1510」とかになっちゃう・・・

その時に気づけばいいものの、入力する数値によっては、気づかず次の入力項目へ・・・なんてこともありまして。

解決

        protected override void OnEnter(System.EventArgs e)
        {
            //全選択
            this.SelectAll();
        }

今までは、OnEnterメソッドをオーバーライドして書いてたんです。

ただ、これだと、マウスクリック時に全選択になってくれない。

タブ移動のは、OnEnterでアクティブになったタイミングで全選択になるのに・・・

じゃあ、どうしましょう?

って、別プロジェクトのソースひっくり返してみたら、なんか動いてるやつがあったので、コピペw

        protected override void OnEnter(System.EventArgs e)
        {
            //全選択
            this.BeginInvoke(new MethodInvoker(() => this.SelectAll()));
        }

これで、マウスクリック時(1回目)でもTextBoxの中身が全選択される。

https://social.msdn.microsoft.com/Forums/ja-JP/9d7864ac-af62-4af0-8f47-7575a6beb25b/textbox125011245712540124591247321462244712617812289textbox208691243?forum=csharpgeneralja

MSのコミュニティでも質問されてたけど、クリックイベントで拾えとか言われてもなぁ・・・って感じだった。

後は、TextBoxとしては、それが正しい挙動です!って言われても、それを何とかしたいんだよ・・・。

そうやって、お客さんに説明して納得してもらえるなら、どんなに楽かw

クリックイベントで単純に処理させたら、何回クリックしようが、ずっと全選択のまま。

2回目以降のクリックを判定するか、全選択されてたら全選択しないとか、別の処理を書くのも面倒くさい。

最後のほうに回答されてたけど、こんな感じの処理は必要になるのかな・・・と。

私の場合、マウスクリック時の全選択の挙動を突き詰めていくと、1回目は全選択する、2回目はクリックした位置へキャレットを移動したい、という仕様になりました。

芸はありませんが、フラグを使って1回目と2回目のマウスクリックを判別するのがポイントです。

TextBoxの派生クラスで、次の様にメンバ変数とメソッドをオーバーライドします。

private bool firstMouseDown = false;
 
protected override void OnEnter(EventArgs e)
{
    SelectAll();
    base.OnEnter(e);
}
 
protected override void OnMouseDown(MouseEventArgs e)
{
    if (firstMouseDown)
    {
        SelectAll();
        firstMouseDown = false;
    }
    base.OnMouseDown(e);
}
 
protected override void OnMouseEnter(EventArgs e)
{
    if (!this.Focused)
        firstMouseDown = true;
    else
        firstMouseDown = false;
 
    base.OnMouseEnter(e);
}
 
protected override void OnMouseLeave(EventArgs e)
{
    firstMouseDown = false;
    base.OnMouseLeave(e);
}

 

 

これで希望の動作が実現できていると良いのですが。
2007年6月27日 1:01
返信
|
引用

まぁ、正直動作の中身については良く分かってないまま使ってるけど、

        protected override void OnEnter(System.EventArgs e)
        {
            //全選択
            this.BeginInvoke(new MethodInvoker(() => this.SelectAll()));
        }

これで、マウスクリック時(1回目)に全選択にできる。

もちろん、修正だけして放置はしてませんよ?

動作確認して、お客さんの要望を満たせるのが分かったので、採用したんですw
(根拠が薄いw)

 

VB.net版はこちら。







-C#


関連記事

[C#]ToStringメソッドで簡単に桁区切りを実現する方法

結論 ToStringメソッドと書式設定で解決。 int a = 1; int b = 1; int ab = a * b; string c = ""; //「1」になる c = …

[C#]$を使ったstring.formatの別の書き方

str += $"(文字列) = {x}"; 保守で、機能修正を行う必要があって、修正をしていたところ、こんな書き方をしているプログラムがありまして・・・ なんだこりゃ??? とな …

Excelでシートをコピーする時に、「名前が既に存在します。」と言われるのを回避して、Excel出力を早くしたい。

結論から書いてしまうと、名前の重複を削除しても、Excelの出力は別に早くならなかった。 早くなるという意味だと、手動でシートをコピーした時に、いちいちダイアログの対応をしなくて済むので、自分で作業し …

C# OracleDbAccessを使用して、SQL実行時にORA-00911 文字が無効です のエラー

表題のとおり、C#でOracleDbAccessを使用して、SQLを実行させる時に発生しました。 ネットで探すと、 全角スペースが原因 とか出てきたので、SQL内のスペースを全て半角スペースに置き換え …

[C#]リストをカンマ区切りの文字列で出力する

リストの項目をカンマ区切りで出力したい 卵が先か鶏が先か~って話じゃないんですが、リストで出力した内容をカンマ区切りのデータにする必要が出てきたので、調べました。 List<string> …


カテゴリー