TextBox
次のように文字列に設定したC#のを含むフォームがあります。
textBox.Text = str;
フォームが表示されているときに、texbox内のテキストが強調表示/選択されて表示されるのはなぜですか?
TextBox
次のように文字列に設定したC#のを含むフォームがあります。
textBox.Text = str;
フォームが表示されているときに、texbox内のテキストが強調表示/選択されて表示されるのはなぜですか?
回答:
テキストボックスのaTabIndex
は0で、TabStop
trueに設定されています。これは、フォームが表示されたときにコントロールにフォーカスが与えられることを意味します。
別のコントロールに0 TabIndex
(存在する場合)を指定してテキストボックスに別のタブインデックス(> 0)を指定するかTabStop
、テキストボックスをfalseに設定してこれが発生しないようにすることができます。
WindowsフォームのTextBoxのデフォルトの動作では、テキストにタブで移動して初めてフォーカスされた場合はすべてのテキストが強調表示されますが、クリックされた場合は強調表示されません。TextBox
のOnGotFocus()
オーバーライドを見ると、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
は、TextBox
のselectionSet
変数が反転します。上記の場合、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()で毎回テキストの選択を解除したくなるかもしれませんが、ユーザーがフィールドからタブで移動して戻った場合、ユーザーのハイライトが失われます。
醜い?もちろんです。しかし、それはそれが何であるかです。
この質問への回答は、同様の問題で私を大いに助けましたが、単純な回答は、他の多くの複雑な提案でのみ示唆されています。テキストを設定SelectionStart
した0
後、に設定するだけです。問題が解決しました!
例:
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
次を開いて、フォームのコントロールのタブ順序を選択することもできます。
表示->タブ順序
このオプションは、フォームデザインビューを開いている場合にのみ「表示」で使用できることに注意してください。
「タブ順序」を選択すると、フォームのビューが開き、コントロールをクリックして目的のタブ順序を選択できます。
VS 2013でテキストフィールドのハイライトを解除するには、次のコマンドで初期化してみてください。
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
そして、メソッドを追加します。
public void myTextBox_GotFocus(object sender, EventArgs e)
{
myTextBox.SelectionLength=0;
}
これをC#でテストしていませんが、C ++ WIN32ダイアログボックスを使用して同じ問題が発生しました。またはFALSE
から戻ることで動作を変更できるようです。お役に立てれば。OnInitDialog()
WM_INITDIALOG