none
TextBoxフォーカス取得時、TextBox内を全選択(反転表示)させたい

    質問

  • TextBoxフォーカス取得時、次の様な感じでTextBox内を全選択(反転表示)

    させようと思っているのですが。

     

          private void textBox2_Enter(object sender, EventArgs e)
            {
                if (textBox2.Text.Length > 0)
                {
                    textBox2.SelectAll();
                }
            }

     

    Tabキーによるフォーカス移動の場合はこれで問題なく全選択させる事が

    できるのですが、マウスによりTextBoxをクリックした場合、Enterイベントは

    発生し、ちゃんと、SelectAllメソッドも実行されるのですが、全選択されません。

    (マウスクリックにより全選択が解除されているのかも。マウスクリックした

    位置でキャレットが点滅しているので)

     

    何か良策はございませんでしょうか?

    宜しくお願いします。

     

    環境

    Windows Vista Ultimate

    Visual Studio 2005 Professional Edition SP1

    2007年6月15日 7:17

回答

  • 遅レスですが、以下ではどうでしょう。

    Code Snippet
    private void textBox1_Enter(object sender, EventArgs e)
    {
        BeginInvoke(new EventHandler(TextBoxSelectAll), sender, e);
    }

    private void TextBoxSelectAll(object sender, EventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (textBox == null) return;

        // 少し長めにクリックされた場合にも一応対処
        while ((Control.MouseButtons & MouseButtons.Left) != MouseButtons.None)
            Application.DoEvents();

        textBox.SelectAll();
    }

     

    2007年6月26日 2:01
  • 私の場合、マウスクリック時の全選択の挙動を突き詰めていくと、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

すべての返信

  •  ぶるーの さんからの引用
    Tabキーによるフォーカス移動の場合はこれで問題なく全選択させる事ができるのですが、マウスによりTextBoxをクリックした場合、Enterイベントは発生し、ちゃんと、SelectAllメソッドも実行されるのですが、全選択されません。(マウスクリックにより全選択が解除されているのかも。マウスクリックした位置でキャレットが点滅しているので)

    それが一般的なので対策する必要がないと思います。実際、Windows の中でもそのようになっています。
    ユーザーがマウスで選択した位置から修正したい場合、全選択状態になったら腹が立つでしょう。

    VB6 の GotFocus イベントではマウスの選択でも全選択状態になっていました。 ぶるーのさんとは逆で、私はそれがイヤで上記のような対策をしていました。
    2007年6月15日 7:51
  • 回答ではないのですが、

     

    それが一般的なので対策する必要がないと思います。実際、Windows の中でもそのようになっています。

     

    Internet Explorer やExplorerのアドレス欄はマウスでクリックでも全選択になります。

     

    >ユーザーがマウスで選択した位置から修正したい場合、全選択状態になったら腹が立つでしょう。

    立ちますね。

    #すみません、横道にそれました。

     

     

    2007年6月15日 8:12
  •  よねKEN さんからの引用
    Internet Explorer やExplorerのアドレス欄はマウスでクリックでも全選択になります。

    アドレス欄は ComboBox 系なので、該当しないと思っていました。
    これに関してはコピペしやすいので、あまり腹が立ちません。
    ttp リンクの時にはクリック -> Ctrl + V -> Home -> h なんてよくやりませんか?

    私が想定していたのは、「マイ コンピュータ」 や 「マイ ドキュメント」 のプロパティなどで表示される TextBox です。
    2007年6月15日 8:46
  •  ぶるーの さんからの引用

    Tabキーによるフォーカス移動の場合はこれで問題なく全選択させる事が

    できるのですが、マウスによりTextBoxをクリックした場合、Enterイベントは

    発生し、ちゃんと、SelectAllメソッドも実行されるのですが、全選択されません。


    TextBoxのClickイベントでやってみて下さい。一度目のクリックで全選択し、二度目のクリックでそれが解除されてキャレットが表示されるようにすると良いでしょう。
    最初のClickでそのTextBoxのIDを記憶しておき、次にClickした際に同じIDだと解除するようにします。TextBoxから離れたとき、つまりLeaveイベントで記憶していたIDをクリアします。
    このClickとLeaveのイベントプロシージャは、各TextBox共通にしてしまいましょう。つまり、各TextBoxで同じClickとLeaveのイベントプロシージャを使うようにして下さい。

    また、カスタムコントロールにしてもいいかもしれませんね。もちろん内部のロジックは上とは異なったものになります。

     

    実はTextBoxでもこのような全選択をさせたい場合があります。TextBoxの中身が文字列だと全選択は余計なお世話になるケースが多いのですが、数字の場合は効果的です。数字の場合は修正するよりも全てを打ち直した方が、一般的には速くて正確なケースが多いからです。

    2007年6月15日 13:15
    モデレータ
  •  trapemiya さんからの引用
    TextBoxのClickイベントでやってみて下さい。一度目のクリックで全選択し、二度目のクリックでそれが解除されてキャレットが表示されるようにすると良いでしょう。
    最初のClickでそのTextBoxのIDを記憶しておき、次にClickした際に同じIDだと解除するようにします。TextBoxから離れたとき、つまりLeaveイベントで記憶していたIDをクリアします。
    このClickとLeaveのイベントプロシージャは、各TextBox共通にしてしまいましょう。つまり、各TextBoxで同じClickとLeaveのイベントプロシージャを使うようにして下さい。

    [Tab] でフォーカス遷移後に Click イベントが発生した時はどうなるでしょうか。
    また ID とありますが、これはなんでしょうか? よくわかりませんが、「参照」 自体を確保しておいた方が確実です。

    実はTextBoxでもこのような全選択をさせたい場合があります。TextBoxの中身が文字列だと全選択は余計なお世話になるケースが多いのですが、数字の場合は効果的です。数字の場合は修正するよりも全てを打ち直した方が、一般的には速くて正確なケースが多いからです。

    勘定系に多そうなお話ですが、実際の現場を覗いてみると彼女たちはマウスを使っていないのですね。
    2007年6月16日 6:02
  •  じゃんぬねっと さんからの引用

    [Tab] でフォーカス遷移後に Click イベントが発生した時はどうなるでしょうか。
    また ID とありますが、これはなんでしょうか? よくわかりませんが、「参照」 自体を確保しておいた方が確実です。

    失礼しました。IDはプロパティのようなイメージを与えてしまい、不適切でしたね。言われるように参照だと確実です。
    Tabで移ってきた場合ですか? するどいところを突きますね。(^^; それは禁じ手です。(ウソ)
    Enterイベントで参照をセットするかなぁ?
    いずれにしてもフォローありがとうございます。

     じゃんぬねっと さんからの引用

    勘定系に多そうなお話ですが、実際の現場を覗いてみると彼女たちはマウスを使っていないのですね。

    彼女たちが、あまりしないかもしれませんがマウスでそのTextBoxをクリックした場合のデフォルトの動作が、全選択された状態の方がいいんじゃないかということなんです。

    2007年6月16日 8:25
    モデレータ
  • じゃんぬねっとさん、よねKENさん、trapemiyaさん、回答ありがとうございます。

     

    当方、マウスクリックによるフォーカス移動時も全選択が必要になるので、

    Enterイベント以外に、マウス系のイベントと組み合わせてやってみます。

     

    ありがとうございます。

     

    2007年6月19日 4:50
  • 遅レスですが、以下ではどうでしょう。

    Code Snippet
    private void textBox1_Enter(object sender, EventArgs e)
    {
        BeginInvoke(new EventHandler(TextBoxSelectAll), sender, e);
    }

    private void TextBoxSelectAll(object sender, EventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (textBox == null) return;

        // 少し長めにクリックされた場合にも一応対処
        while ((Control.MouseButtons & MouseButtons.Left) != MouseButtons.None)
            Application.DoEvents();

        textBox.SelectAll();
    }

     

    2007年6月26日 2:01
  • 私の場合、マウスクリック時の全選択の挙動を突き詰めていくと、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
  • TH01さん、t_suzukiさん、回答ありがとうございます。

     

    ソースまで付けて頂いて、大変参考になります。

     

    皆様の情報で何とかできそうです。

     

    ありがとうございました。

     

    2007年6月27日 8:28