@fletcher: Todavía no he tenido tiempo de mirarlo. Daré la respuesta en unos días.
CJ7
Puede agregar una etiqueta vb.net, ya que el problema es realmente el mismo y la respuesta aceptada también es válida
Andrea Antonangeli
La respuesta de BenSmith relacionada con la visualización del orden de tabulación será muy útil en este escenario.
Samitha Chathuranga
Respuestas:
128
El cuadro de texto tiene un valor TabIndexde 0 y se TabStopestablece en verdadero. Esto significa que se le dará foco al control cuando se muestre el formulario.
Puede darle a otro control el 0 TabIndex(si hay uno) y darle al cuadro de texto un índice de pestaña diferente (> 0), o establecer TabStopen falso para que el cuadro de texto evite que esto suceda.
¿Está seguro de que el cuadro de texto TabIndex está establecido en 0? ¿Viene de su comportamiento?
26071986
@ 26071986 - Bueno, hice una prueba rápida. Si, en un formulario con un cuadro de texto y un botón, cambio el texto dentro del cuadro de texto en el constructor cuando el tabindex se establece en 0, el texto se resalta. Si el botón tiene el índice de tabulación 0 y el índice de tabulación del cuadro de texto es> 0, el texto no se resalta.
fletcher
De hecho, parece tener que ver con TabIndex, solo que cambié todos los índices de pestañas de mis elementos de manera apropiada (eso pensé). Resulta que los grupos también tienen índices de pestañas que debes cambiar, así como todos los elementos que los contienen. Entonces, aunque configuré pestañas de elementos del 1 al 9, un grupo todavía tenía 0, por lo que el cuadro de texto en ese grupo se convirtió en el primer elemento activado (por lo tanto, tenía su contenido resaltado).
deed02392
1
No está necesariamente relacionado con tener TabIndex = 0, pero ciertamente sucede si el TextBox tiene el TabIndex MÁS BAJO del formulario. Para verificar: establezca TabIndex = 5 en el TextBox y establezca un número mayor que 5 en todos los TabIndex de los otros controles del formulario.
Andrea Antonangeli
Esto también sucede cuando selecciona una nueva TabPage en un TabControl. La misma solución funciona.
JonP
44
El comportamiento predeterminado de un TextBox en Windows Forms es resaltar todo el texto si se enfoca por primera vez al tabularlo, pero no si se hace clic en él. Podemos ver esto en el reflector mirando el TextBox's OnGotFocus()de anulación:
Es esa declaración if la que está causando el comportamiento que no nos gusta. Además, para colmo de males, el Textautor de la propiedad restablece ciegamente esa selectionSetvariable cada vez que se reasigna el texto:
publicoverridestring Text
{
get
{
returnbase.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
Entonces, si tiene un TextBox y una pestaña en él, se seleccionará todo el texto. Si hace clic en él, se elimina el resaltado y, si vuelve a tabular, se conserva la posición del cursor (y la longitud de selección de cero). Pero si configuramos programáticamente nuevo Text, y volvemos a tabular en el TextBox, entonces todo el texto se seleccionará nuevamente.
Si usted es como yo y encuentra este comportamiento molesto e inconsistente, entonces hay dos formas de solucionar este problema.
El primero, y probablemente el más fácil, es simplemente activar la configuración de selectionSetllamando DeselectAll()al formulario Load()y siempre que los Textcambios:
( DeselectAll()Sólo conjuntos SelectionLengtha cero. En realidad es SelectionStartque voltea la TextBox's selectionSetvariables. En el caso anterior, el llamado a DeselectAll()no es necesaria, ya que estamos estableciendo el principio hasta el final del texto. Pero si lo ponemos a cualquier otra posición, al igual el comienzo del texto, luego llamarlo es una buena idea).
La forma más permanente es crear nuestro propio TextBox con el comportamiento deseado a través de la herencia:
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;
}
}
}
Quizás tenga la tentación de no llamar base.OnGotFocus(), pero entonces perderíamos funcionalidad útil en la Controlclase base . Y es posible que tenga la tentación de no meterse con las selectionSettonterías en absoluto y simplemente anular la selección del texto cada vez en OnGotFocus (), pero luego perderíamos el resaltado del usuario si saliera del campo y regresara.
Las respuestas a esta pregunta me ayudaron mucho con un problema similar, pero la respuesta simple solo se insinúa con muchas otras sugerencias complejas. Sólo hay que establecer SelectionStartque 0después de ajustar el texto. ¡Problema resuelto!
También puede elegir el orden de las pestañas para los controles de su formulario abriendo:
Ver-> Orden de tabulación
Tenga en cuenta que esta opción solo está disponible en "Ver" si tiene abierta la vista Diseño de formulario.
Al seleccionar "Orden de tabulación" se abre una vista del formulario que le permite elegir el orden de tabulación deseado haciendo clic en los controles.
Esto haría que el texto se deseleccionara si previamente enfocó el cuadro de texto, seleccionó algún texto en él, se alejó de él y luego lo enfocó nuevamente.
Stewart
0
No he probado esto en C # pero encontré el mismo problema usando un cuadro de diálogo C ++ WIN32. Parece que puedes cambiar el comportamiento volviendo FALSEde OnInitDialog()o WM_INITDIALOG. Espero que esto ayude.
Respuestas:
El cuadro de texto tiene un valor
TabIndex
de 0 y seTabStop
establece en verdadero. Esto significa que se le dará foco al control cuando se muestre el formulario.Puede darle a otro control el 0
TabIndex
(si hay uno) y darle al cuadro de texto un índice de pestaña diferente (> 0), o establecerTabStop
en falso para que el cuadro de texto evite que esto suceda.fuente
El comportamiento predeterminado de un TextBox en Windows Forms es resaltar todo el texto si se enfoca por primera vez al tabularlo, pero no si se hace clic en él. Podemos ver esto en el reflector mirando el
TextBox
'sOnGotFocus()
de anulación: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(); } } }
Es esa declaración if la que está causando el comportamiento que no nos gusta. Además, para colmo de males, el
Text
autor de la propiedad restablece ciegamente esaselectionSet
variable cada vez que se reasigna el texto:public override string Text { get { return base.Text; } set { base.Text = value; this.selectionSet = false; } }
Entonces, si tiene un TextBox y una pestaña en él, se seleccionará todo el texto. Si hace clic en él, se elimina el resaltado y, si vuelve a tabular, se conserva la posición del cursor (y la longitud de selección de cero). Pero si configuramos programáticamente nuevo
Text
, y volvemos a tabular en el TextBox, entonces todo el texto se seleccionará nuevamente.Si usted es como yo y encuentra este comportamiento molesto e inconsistente, entonces hay dos formas de solucionar este problema.
El primero, y probablemente el más fácil, es simplemente activar la configuración de
selectionSet
llamandoDeselectAll()
al formularioLoad()
y siempre que losText
cambios:protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.textBox2.SelectionStart = this.textBox2.Text.Length; this.textBox2.DeselectAll(); }
(
DeselectAll()
Sólo conjuntosSelectionLength
a cero. En realidad esSelectionStart
que voltea laTextBox
'sselectionSet
variables. En el caso anterior, el llamado aDeselectAll()
no es necesaria, ya que estamos estableciendo el principio hasta el final del texto. Pero si lo ponemos a cualquier otra posición, al igual el comienzo del texto, luego llamarlo es una buena idea).La forma más permanente es crear nuestro propio TextBox con el comportamiento deseado a través de la herencia:
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; } } }
Quizás tenga la tentación de no llamar
base.OnGotFocus()
, pero entonces perderíamos funcionalidad útil en laControl
clase base . Y es posible que tenga la tentación de no meterse con lasselectionSet
tonterías en absoluto y simplemente anular la selección del texto cada vez en OnGotFocus (), pero luego perderíamos el resaltado del usuario si saliera del campo y regresara.¿Feo? Puedes apostar. Pero es lo que es.
fuente
Las respuestas a esta pregunta me ayudaron mucho con un problema similar, pero la respuesta simple solo se insinúa con muchas otras sugerencias complejas. Sólo hay que establecer
SelectionStart
que0
después de ajustar el texto. ¡Problema resuelto!Ejemplo:
yourtextbox.Text = "asdf"; yourtextbox.SelectionStart = 0;
fuente
También puede elegir el orden de las pestañas para los controles de su formulario abriendo:
Ver-> Orden de tabulación
Tenga en cuenta que esta opción solo está disponible en "Ver" si tiene abierta la vista Diseño de formulario.
Al seleccionar "Orden de tabulación" se abre una vista del formulario que le permite elegir el orden de tabulación deseado haciendo clic en los controles.
fuente
Para quitar el resaltado de un campo de texto, con VS 2013, intente init con:
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
Y agregue el método:
public void myTextBox_GotFocus(object sender, EventArgs e) { myTextBox.SelectionLength=0; }
fuente
No he probado esto en C # pero encontré el mismo problema usando un cuadro de diálogo C ++ WIN32. Parece que puedes cambiar el comportamiento volviendo
FALSE
deOnInitDialog()
oWM_INITDIALOG
. Espero que esto ayude.fuente