![](/img/trans.png)
[英]How do I stop the text in a Winforms textbox from being automatically selected/highlighted when first displayed?
[英]Why is text in TextBox highlighted (selected) when form is displayed?
我有一个包含 C# 中的TextBox
的表单,我将其设置为一个字符串,如下所示:
textBox.Text = str;
显示表单时,为什么 texbox 中的文本会突出显示/选中?
文本框的TabIndex
为 0, TabStop
设置为 true。 这意味着在显示表单时控件将获得焦点。
您可以为另一个控件指定 0 TabIndex
(如果有)并为文本框指定不同的选项卡索引 (>0),或者将文本框的TabStop
设置为 false 以阻止这种情况发生。
Windows 窗体中 TextBox 的默认行为是在第一次通过 Tab 键进入焦点时突出显示所有文本,但如果单击进入则不会突出显示。 我们可以通过查看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
属性的 setter 都会盲目地重置selectionSet
变量:
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
因此,如果您有一个 TextBox 并按 Tab 键进入其中,则所有文本都将被选中。 如果您点击它,突出显示将被删除,如果您重新进入它,您的插入符号位置(和选择长度为零)将被保留。 但是,如果我们以编程方式设置 new Text
,然后再次 Tab 进入 TextBox,那么所有文本都将再次被选中。
如果您像我一样发现这种行为令人讨厌且不一致,那么有两种方法可以解决此问题。
第一个,也可能是最简单的,是通过在表单Load()
上调用DeselectAll()
Load()
并在Text
更改时简单地触发selectionSet
的设置:
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;
您还可以通过打开以下选项来选择表单控件的 Tab 键顺序:
查看->标签顺序
请注意,如果您打开了表单设计视图,则此选项仅在“视图”中可用。
选择“Tab Order”打开一个窗体视图,允许您通过单击控件来选择所需的 Tab 顺序。
要使用 VS 2013 取消突出显示文本字段,请尝试使用以下命令进行初始化:
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
并添加方法:
public void myTextBox_GotFocus(object sender, EventArgs e)
{
myTextBox.SelectionLength=0;
}
我没有在 C# 上测试过这个,但我在使用 C++ WIN32 对话框时遇到了同样的问题。 似乎您可以通过从OnInitDialog()
或WM_INITDIALOG
返回FALSE
来更改行为。 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.