フォームが表示されているときにTextBoxのテキストが強調表示(選択)されるのはなぜですか?


84

TextBox次のように文字列に設定したC#のを含むフォームがあります。

textBox.Text = str;

フォームが表示されているときに、texbox内のテキストが強調表示/選択されて表示されるのはなぜですか?



これをなんとか整理できましたか?これをどのように修正しましたか?
fletcher 2010

@fletcher:私はまだそれを見ることに慣れていません。数日以内に回答を差し上げます。
CJ7 2010

問題は実際には同じであり、受け入れられた回答も有効であるため、vb.netタグを追加できます
Andrea Antonangeli 2014

タブオーダーの表示に関連するBenSmithの回答は、このようなシナリオで非常に役立ちます。
Samitha Chathuranga 2015

回答:


128

テキストボックスのaTabIndexは0で、TabStoptrueに設定されています。これは、フォームが表示されたときにコントロールにフォーカスが与えられることを意味します。

別のコントロールに0 TabIndex(存在する場合)を指定してテキストボックスに別のタブインデックス(> 0)を指定するかTabStop、テキストボックスをfalseに設定してこれが発生しないようにすることができます。


1
テキストボックスのTabIndexが0に設定されていますか?それはその行動から出てきますか?
26071986 2010

@ 26071986-さて、私は簡単なテストを実行しました。1つのテキストボックスとボタンがあるフォームで、tabindexが0に設定されているときにコンストラクターのテキストボックス内のテキストを変更すると、テキストが強調表示されます。ボタンのタブインデックスが0で、テキストボックスのタブインデックスが> 0の場合、テキストは強調表示されません。
fletcher 2010

それは確かにTabIndexに関係しているようです-私だけがすべての要素のタブインデックスを適切に変更しました(私は思った)。グループには、変更する必要のあるタブインデックスと、それに含まれるすべての要素も含まれていることがわかりました。したがって、1〜9の要素タブを設定しましたが、グループにはまだ0が含まれていたため、そのグループのテキストボックスが最初にアクティブ化された要素になりました(したがって、その内容が強調表示されました)。
deed02392 2013年

1
TabIndex = 0である必要はありませんが、TextBoxのTabIndexがフォームの中で最も低い場合は確かに発生します。確認するには:TextBoxでTabIndex = 5を設定し、フォームの他のコントロールのすべてのTabIndexで5より大きい数値を設定します。
アンドレアアントナンジェリ2014年

これは、TabControlで新しいTabPageを選択したときにも発生します。同じ解決策が機能します。
JonP

43

WindowsフォームのTextBoxのデフォルトの動作では、テキストにタブで移動して初めてフォーカスされた場合はすべてのテキストが強調表示されますが、クリックされた場合は強調表示されません。TextBoxOnGotFocus()オーバーライドを見ると、Reflectorでこれを確認できます。

protected override void OnGotFocus(EventArgs e)
{
    base.OnGotFocus(e);
    if (!this.selectionSet)
    {
        this.selectionSet = true;
        if ((this.SelectionLength == 0) && (Control.MouseButtons == MouseButtons.None))
        {
            base.SelectAll();
        }
    }
}

それは、私たちが好まない動作を引き起こしているifステートメントです。さらに、怪我に侮辱を加えるために、TextプロパティのセッターselectionSetは、テキストが再割り当てされるたびにその変数を盲目的にリセットします。

public override string Text
{
    get
    {
        return base.Text;
    }
    set
    {
        base.Text = value;
        this.selectionSet = false;
    }
}

したがって、TextBoxとタブがある場合は、すべてのテキストが選択されます。クリックするとハイライトが削除され、再度タブで移動すると、キャレットの位置(および選択長がゼロ)が保持されます。ただし、プログラムでnewを設定Textし、TextBoxに再度Tabキーを押すと、すべてのテキストが再度選択されます。

あなたが私のようで、この振る舞いが煩わしく一貫性がないと感じた場合、この問題を回避する方法は2つあります。

最初の、そしておそらく最も簡単なのは、フォームをselectionSet呼び出して変更を加えるたびに、の設定をトリガーすることです。DeselectAll()Load()Text

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    this.textBox2.SelectionStart = this.textBox2.Text.Length;
    this.textBox2.DeselectAll();
}

(ゼロにDeselectAll()設定SelectionLengthするだけです。実際にSelectionStartは、TextBoxselectionSet変数が反転します。上記の場合、DeselectAll()テキストの先頭を末尾に設定しているため、を呼び出す必要はありません。ただし、他の位置に設定すると、テキストの始まり、それからそれを呼び出すことは良い考えです。)

より永続的な方法は、継承を通じて目的の動作を備えた独自のTextBoxを作成することです。

public class NonSelectingTextBox : TextBox
{
    // Base class has a selectionSet property, but its private.
    // We need to shadow with our own variable. If true, this means
    // "don't mess with the selection, the user did it."
    private bool selectionSet;

    protected override void OnGotFocus(EventArgs e)
    {
        bool needToDeselect = false;

        // We don't want to avoid calling the base implementation
        // completely. We mirror the logic that we are trying to avoid;
        // if the base implementation will select all of the text, we
        // set a boolean.
        if (!this.selectionSet)
        {
            this.selectionSet = true;

            if ((this.SelectionLength == 0) && 
                (Control.MouseButtons == MouseButtons.None))
            {
                needToDeselect = true;
            }
        }

        // Call the base implementation
        base.OnGotFocus(e);

        // Did we notice that the text was selected automatically? Let's
        // de-select it and put the caret at the end.
        if (needToDeselect)
        {
            this.SelectionStart = this.Text.Length;
            this.DeselectAll();
        }
    }

    public override string Text
    {
        get
        {
            return base.Text;
        }
        set
        {
            base.Text = value;

            // Update our copy of the variable since the
            // base implementation will have flipped its back.
            this.selectionSet = false;
        }
    }
}

を呼び出さないようにしたいと思うかもしれませんbase.OnGotFocus()が、そうすると、基本Controlクラスの便利な機能が失われます。また、selectionSetナンセンスをまったくいじらずに、OnGotFocus()で毎回テキストの選択を解除したくなるかもしれませんが、ユーザーがフィールドからタブで移動して戻った場合、ユーザーのハイライトが失われます。

醜い?もちろんです。しかし、それはそれが何であるかです。


31

この質問への回答は、同様の問題で私を大いに助けましたが、単純な回答は、他の多くの複雑な提案でのみ示唆されています。テキストを設定SelectionStartした0後、に設定するだけです。問題が解決しました!

例:

yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;

4

次を開いて、フォームのコントロールのタブ順序を選択することもできます。

表示->タブ順序

このオプションは、フォームデザインビューを開いている場合にのみ「表示」で使用できることに注意してください。

「タブ順序」を選択すると、フォームのビューが開き、コントロールをクリックして目的のタブ順序を選択できます。


1
これは私を大いに助けました。実際には、タブの順序に関係する場合、タブのインデックスは重要ではありません。
Samitha Chathuranga 2015

1

VS 2013でテキストフィールドのハイライトを解除するには、次のコマンドで初期化してみてください。

myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);

そして、メソッドを追加します。

public void myTextBox_GotFocus(object sender, EventArgs e)
{
    myTextBox.SelectionLength=0;
}

これにより、以前にテキストボックスにフォーカスを置き、その中のテキストを選択し、そこから移動してから再度フォーカスした場合、テキストの選択が解除されます。
スチュワート

0

これをC#でテストしていませんが、C ++ WIN32ダイアログボックスを使用して同じ問題が発生しました。またはFALSEから戻ることで動作を変更できるようです。お役に立てれば。OnInitDialog()WM_INITDIALOG


1
Windows APIはwinforms内にカプセル化されているため、これはあまり役に立たないと思います。
ネイサンA
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.