为什么在显示表单时,文本框中的文本突出显示(选中)?

我有一个包含在C#中的文本框,我设置为一个string,如下所示:

textBox.Text = str; 

显示表单时,为什么texbox中的文本突出显示/选中?

该文本框的TabIndex为0, TabStop设置为true。 这意味着当窗体被显示时,控件将被赋予焦点。

您可以给另一个控件0 TabIndex (如果有的话),并给文本框一个不同的标签索引(> 0),或者设置TabStop为false的文本框来阻止这种情况发生。

Windows窗体中TextBox的默认行为是突出显示所有的文本,如果它通过标签首次被关注,而不是被点击进去。 我们可以在Reflector中看到TextBoxOnGotFocus()覆盖:

 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(); } } } 

这就是说,如果陈述是造成我们不喜欢的行为。 此外,为了增加伤害, Text属性的设置者在文本被重新分配时盲目地重置该selectionSetvariables:

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

所以如果你有一个文本框和标签,所有的文本将被选中。 如果点击它,突出显示被删除,如果您重新插入它,您的插入位置(和select长度零)被保留。 但是,如果我们以编程方式设置新的Text ,并再次标签到文本框,那么所有的文本将被再次select。

如果你像我一样,发现这种行为烦人和不一致,那么围绕这个问题有两种方法。

第一种,也可能是最简单的,只需通过在Load()上调用DeselectAll() ,并在Text发生变化时触发selectionSet的设置:

 protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.textBox2.SelectionStart = this.textBox2.Text.Length; this.textBox2.DeselectAll(); } 

DeselectAll()只是将SelectionLength设置为零,实际上是SelectionStart ,它翻转了TextBoxselectionSetvariables,在这种情况下,调用DeselectAll()并不是必须的,因为我们将start设置为文本的结尾。如果我们把它设置到任何其他位置,如文本的开始,那么调用它是个好主意。)

更持久的方法是通过inheritance创build我们自己的文本框与所需的行为:

 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类中我们会失去有用的function。 而且你可能会试图不要惹起selectionSet胡扯,只需在OnGotFocus()中每次取消select该文本,但是如果用户标签出现在字段后面,则会丢失用户的高亮。

丑陋? 完全正确。 但是它就是这样啊。

这个问题的答案帮助了我很多类似的问题,但简单的答案只是暗示与其他很多复杂的build议。 设置文本后,只需将SelectionStart设置为0。 问题解决了!

例:

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

您也可以通过打开以下选项来select表单控件的Tab键顺序:

查看 – >标签顺序

请注意,如果打开窗体devise视图,则此选项仅在“查看”中可用。

select“制表顺序”打开窗体的视图,允许您通过单击控件select所需的制表顺序。

为了避免使用VS 2013的文本字段,请尝试使用init:

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

并添加方法:

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

我没有在C#上testing过,但是我用C ++ WIN32对话框遇到了同样的问题。 好像你可以通过从OnInitDialog()或WM_INITDIALOG返回FALSE来改变行为。 希望这可以帮助。