我在C#中有一个包含TextBox
的表单,我将其设置为字符串,如下所示:
textBox.Text = str;
显示表单时,为什么texbox中的文本会突出显示/选中?
答案 0 :(得分:112)
文本框的TabIndex
为0,TabStop
设置为true。这意味着在显示表单时将为焦点控件提供焦点。
你可以给另一个控件0 TabIndex
(如果有的话)并给文本框一个不同的选项卡索引(> 0),或者为文本框设置TabStop
为false阻止这种情况发生。
答案 1 :(得分:41)
Windows窗体中TextBox的默认行为是突出显示所有文本,如果它首次通过Tab键进行聚焦,但如果被单击则不会。我们可以通过查看TextBox
的{{1}}覆盖:
OnGotFocus()
这是if语句导致我们不喜欢的行为。此外,为了增加对伤害的侮辱,只要重新分配文本,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();
}
}
}
属性的setter就会盲目地重置Text
变量:
selectionSet
因此,如果您有一个TextBox和选项卡,则将选择所有文本。如果单击它,则会删除突出显示,如果重新标记,则会保留您的插入符号位置(以及选择长度为零)。但是,如果我们以编程方式将新的public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
和tab再次设置到TextBox中,那么将再次选择所有文本。
如果你像我一样发现这种行为令人讨厌且不一致,那么解决这个问题有两种方法。
第一个,也可能是最简单的,只需在表单Text
上调用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
的{{1}}变量。在上述情况下,调用到TextBox
是没有必要的,因为我们将开头设置为文本的结尾。但是如果我们将它设置为任何其他位置,比如文本的开头,那么调用它是一个好主意。)
更永久的方法是通过继承创建具有所需行为的自己的TextBox:
selectionSet
您可能想要不调用DeselectAll()
,但我们会失去基础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()
胡说八道,只是在OnGotFocus()中每次都取消选择文本,但如果他们从字段中退出并返回,我们就会丢失用户的突出显示。
丑?完全正确。但事实就是如此。
答案 2 :(得分:26)
这个问题的答案帮助了我很多类似的问题,但简单的答案只是暗示了很多其他复杂的建议。设置文本后,只需将SelectionStart设置为0即可。问题解决了!
示例:
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
答案 3 :(得分:3)
您还可以通过以下方式选择表单控件的Tab键顺序:
查看 - >标签顺序
请注意,此选项仅适用于" View"如果您打开了表单设计视图。
选择" Tab Order"打开表单视图,您可以通过单击控件选择所需的Tab键顺序。
答案 4 :(得分:1)
要取消突出显示文本字段,请使用VS 2013尝试使用init:
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
并添加方法:
public void myTextBox_GotFocus(object sender, EventArgs e)
{
myTextBox.SelectionLength=0;
}
答案 5 :(得分:0)
我还没有在C#上测试过这个问题但是我使用C ++ WIN32对话框遇到了同样的问题。看起来你可以通过从OnInitDialog()或WM_INITDIALOG返回FALSE来改变行为。希望这会有所帮助。