[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#


関連記事

ORACLEでORA-01861: リテラルが書式文字列と一致しません

ORA-01861: リテラルが書式文字列と一致しません このエラー、ぶっちゃけ、意味が分からないところでもある。 日付の指定時に発生してて、原因が判明するまでに結構回り道をしました。 ネットで検索し …

[C#]systemcolorを使う

ボタンとかを作成した時に、BackColorとかにデフォルトで設定される色を変更したいけど、何かのアクション以外は、デフォルト職を使いたい。 って時に多分使える。 SystemColorsクラス(Mi …

no image

ToolTip(ツールチップ)のPictureBoxに登録ものが表示されなくなった

PictureBoxに関連付けてたToolTip(ツールチップ)が表示されなくなる~C# http://ameblo.jp/oregano-blog/theme-10017227400.html 事の …

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

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

OracleDataaccessでどハマリして、勉強になったとかじゃなくお客さんに迷惑かけたし、もう穴を掘って埋まりたい

みんなは、どうやってOracleDataaccessを筆頭に、複数バージョンが入り乱れるDLLを管理してるのか教えてください。 マジで。


カテゴリー