У меня есть форма, содержащая a TextBox
на C #, которую я установил в строку следующим образом:
textBox.Text = str;
Почему при отображении формы текст в текстовом поле выделяется / выделяется?
У меня есть форма, содержащая a TextBox
на C #, которую я установил в строку следующим образом:
textBox.Text = str;
Почему при отображении формы текст в текстовом поле выделяется / выделяется?
Ответы:
Текстовое поле имеет значение TabIndex
0 и имеет TabStop
значение true. Это означает, что элемент управления будет находиться в фокусе при отображении формы.
Вы можете либо дать другому элементу управления значение 0 TabIndex
(если он есть) и дать текстовому полю другой индекс табуляции (> 0), либо установить TabStop
значение false для текстового поля, чтобы этого не происходило.
Поведение TextBox по умолчанию в Windows Forms заключается в выделении всего текста, если он становится сфокусированным в первый раз, путем перехода к нему, но не при нажатии на него. Мы можем увидеть это в рефлектор, посмотрев на TextBox
«S OnGotFocus()
переопределение:
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, тогда весь текст будет снова выбран.
Если вы похожи на меня и считаете такое поведение раздражающим и непоследовательным, то есть два пути решения этой проблемы.
Первый и, вероятно, самый простой - просто запустить настройку 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
«s 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, попробуйте выполнить init с помощью:
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
. Надеюсь это поможет.