@fletcher: Я еще не успел взглянуть на это. Награду ответ через несколько дней.
CJ7
Вы можете добавить тег vb.net, поскольку проблема действительно та же, и принятый ответ также действителен
Андреа Антонанджели
Ответ BenSmith, связанный с просмотром порядка вкладок, будет очень полезен в таком сценарии.
Самита Чатуранга
Ответы:
130
Текстовое поле имеет значение TabIndex0 и имеет TabStopзначение true. Это означает, что элемент управления будет находиться в фокусе при отображении формы.
Вы можете либо дать другому элементу управления значение 0 TabIndex(если он есть) и дать текстовому полю другой индекс табуляции (> 0), либо установить TabStopзначение false для текстового поля, чтобы этого не происходило.
Вы уверены, что для текстового поля TabIndex установлено значение 0? Это связано с его поведением?
26071986 06
@ 26071986 - Ну, я провел быстрый тест. Если в форме с одним текстовым полем и кнопкой я изменяю текст в текстовом поле в конструкторе, когда для tabindex установлено значение 0, текст выделяется. Если кнопка имеет индекс табуляции 0, а индекс табуляции текстового поля> 0, текст не выделяется.
fletcher
Похоже, это действительно связано с TabIndex - только я соответствующим образом изменил индексы вкладок всех элементов (так я подумал). Оказывается, у групп тоже есть индексы вкладок, которые вам нужно изменить, а также все содержащиеся в них элементы. Итак, пока я настраивал вкладки элементов с 1 по 9, в группе все еще оставалось 0, поэтому текстовое поле в этой группе стало первым активированным элементом (следовательно, его содержимое было выделено).
deed02392 08
1
Это не обязательно связано с наличием TabIndex = 0, но, безусловно, происходит, если TextBox имеет САМЫЙ НИЗКИЙ TabIndex формы. Чтобы проверить: установите TabIndex = 5 в TextBox и установите число больше 5 во всех TabIndex других элементов управления формы.
Андреа Антонанджели
Это также происходит, когда вы выбираете новую вкладку TabPage в TabControl. То же решение работает.
JonP
44
Поведение TextBox по умолчанию в Windows Forms заключается в выделении всего текста, если он становится сфокусированным в первый раз, путем перехода к нему, но не при нажатии на него. Мы можем увидеть это в рефлектор, посмотрев на TextBox«S OnGotFocus()переопределение:
Это оператор if, который вызывает поведение, которое нам не нравится. Кроме того, чтобы добавить оскорбления к травме, Textустановщик свойства вслепую сбрасывает эту selectionSetпеременную всякий раз, когда текст переназначается:
publicoverridestring Text
{
get
{
returnbase.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
Поэтому, если у вас есть TextBox и вкладка, весь текст будет выделен. Если вы щелкнете по нему, выделение будет удалено, а если вы перейдете в него, ваше положение курсора (и длина выделения, равная нулю) сохранится. Но если мы программно установим new Textи снова введем вкладку в TextBox, тогда весь текст будет снова выбран.
Если вы похожи на меня и считаете такое поведение раздражающим и непоследовательным, то есть два пути решения этой проблемы.
Первый и, вероятно, самый простой - просто запустить настройку selectionSet, вызвав DeselectAll()форму Load()и всякий раз, когда Textменяются:
( DeselectAll()Только наборы SelectionLengthк нулю. Это на самом деле , SelectionStartчто переворачивает TextBox«s selectionSetпеременной. В приведенном выше случае, вызов DeselectAll()не является необходимым , так как мы устанавливаем начало в конце текста. Но если мы устанавливаем его в любое другое положение, как начало текста, а затем его вызов - хорошая идея.)
Более постоянный способ - создать наш собственный TextBox с желаемым поведением через наследование:
publicclassNonSelectingTextBox : 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."privatebool selectionSet;
protectedoverridevoidOnGotFocus(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 implementationbase.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();
}
}
publicoverridestring Text
{
get
{
returnbase.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после установки текста. Задача решена!
Это приведет к отмене выделения текста, если вы ранее сфокусировали текстовое поле, выделили в нем какой-то текст, отодвинулись от него, а затем снова сфокусировали его.
Стюарт
0
Я не тестировал это на C #, но я столкнулся с той же проблемой, используя диалоговое окно C ++ WIN32. Кажется, вы можете изменить поведение, вернувшись FALSEиз OnInitDialog()или WM_INITDIALOG. Надеюсь это поможет.
Ответы:
Текстовое поле имеет значение
TabIndex
0 и имеетTabStop
значение true. Это означает, что элемент управления будет находиться в фокусе при отображении формы.Вы можете либо дать другому элементу управления значение 0
TabIndex
(если он есть) и дать текстовому полю другой индекс табуляции (> 0), либо установитьTabStop
значение false для текстового поля, чтобы этого не происходило.источник
Поведение TextBox по умолчанию в Windows Forms заключается в выделении всего текста, если он становится сфокусированным в первый раз, путем перехода к нему, но не при нажатии на него. Мы можем увидеть это в рефлектор, посмотрев на
TextBox
«SOnGotFocus()
переопределение: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
«sselectionSet
переменной. В приведенном выше случае, вызов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
. Надеюсь это поможет.источник