我有一个包含TextBox
C#的表单,我将其设置为字符串,如下所示:
textBox.Text = str;
显示表单时,为什么texbox中的文本突出显示/选中?
我有一个包含TextBox
C#的表单,我将其设置为字符串,如下所示:
textBox.Text = str;
显示表单时,为什么texbox中的文本突出显示/选中?
Answers:
文本框的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
,然后再次使用Tab键进入TextBox,则所有文本将再次被选中。
如果您像我一样,发现这种行为令人讨厌且不一致,那么可以通过两种方法解决此问题。
第一种,也许是最简单的方法,是selectionSet
通过调用DeselectAll()
formLoad()
并在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()中都只是取消选择文本,但是如果用户跳出字段并返回,则会丢失用户的突出显示。
丑陋?完全正确。但是它就是这样啊。
您还可以通过以下方式选择表单控件的选项卡顺序:
查看->标签顺序
请注意,只有打开了表单设计视图,此选项才在“视图”中可用。
选择“制表顺序”将打开窗体的视图,该视图允许您通过单击控件来选择所需的制表顺序。