Tengo un formulario que contiene un TextBoxen C # que configuré en una cadena de la siguiente manera:
textBox.Text = str;
Cuando se muestra el formulario, ¿por qué el texto en el cuadro de texto aparece resaltado / seleccionado?
Tengo un formulario que contiene un TextBoxen C # que configuré en una cadena de la siguiente manera:
textBox.Text = str;
Cuando se muestra el formulario, ¿por qué el texto en el cuadro de texto aparece resaltado / seleccionado?
Respuestas:
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.
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:
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 Textautor de la propiedad restablece ciegamente esa selectionSetvariable 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 selectionSetllamando DeselectAll()al formulario Load()y siempre que los Textcambios:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.DeselectAll();
}
( 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:
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 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.
¿Feo? Puedes apostar. Pero es lo que es.
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!
Ejemplo:
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
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.
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;
}
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.