J'ai un formulaire contenant une zone de texte en C # que j'ai définie comme une chaîne comme suit:
textBox.Text = str;
Quand le formulaire est affiché, pourquoi le texte dans la texbox apparaît-il en surbrillance / sélectionné?
J'ai un formulaire contenant une zone de texte en C # que j'ai définie comme une chaîne comme suit:
textBox.Text = str;
Quand le formulaire est affiché, pourquoi le texte dans la texbox apparaît-il en surbrillance / sélectionné?
Les TabIndex
de 0 et TabStop
texte sont définis sur true. Cela signifie que le contrôle sera mis en évidence lorsque le formulaire est affiché.
Vous pouvez soit donner à un autre contrôle les 0 TabIndex
(s'il en existe un) et attribuer à la zone de texte un index de tabulation différent (> 0), ou définir TabStop
sur false pour la zone de texte. pour empêcher cela de se produire.
Le comportement par défaut d'une zone de texte dans les Windows Forms est pour mettre en surbrillance le texte si il est porté pour la première fois en surbrillance, mais pas si il est cliqué. Nous pouvons voir cela dans un Réflecteur en regardant l' TextBox
s' OnGotFocus()
remplacer:
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();
}
}
}
C'est que, si l'instruction qui est à l'origine du comportement que nous n'aimons pas. En outre, pour ajouter l'insulte à l'injure, l' Text
de la propriété de définition de la aveuglément réinitialise qu' selectionSet
variable à chaque fois que le texte est attribué à nouveau:
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
Donc, si vous avez une zone de texte et onglet en elle, tous les textes seront sélectionnés. Si vous cliquez sur, le point culminant est retiré, et si vous re-onglet dans, votre position du curseur (et de sélection de longueur zéro) est préservée. Mais si nous définir par programmation de nouveaux Text
, et un onglet dans la zone de texte nouveau, puis tout le texte sera sélectionné à nouveau.
Si vous êtes comme moi et de trouver ce comportement gênant et incohérente, puis il y a deux façons de contourner ce problème.
Le premier, et probablement le plus simple, c'est simplement de déclencher le réglage de l' selectionSet
en appelant DeselectAll()
sur le formulaire Load()
et à chaque fois que l' Text
changements:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.DeselectAll();
}
(DeselectAll()
seulement des ensembles SelectionLength
à zéro. C'est en fait SelectionStart
qui permet d'inverser la TextBox
s' selectionSet
variable. Dans le cas ci-dessus, l'appel à l' DeselectAll()
n'est pas nécessaire car nous réglage du début à la fin du texte. Mais si nous avons choisi de toute autre position, comme le début du texte, puis de l'appel, c'est une bonne idée.)
La manière plus permanente est de créer notre propre zone de texte avec le comportement souhaité par le biais de l'héritage:
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;
}
}
}
Vous avez peut-être tenté de tout simplement pas appeler base.OnGotFocus()
, mais nous perdre de fonctionnalité utile dans la base Control
classe. Et vous pourriez être tenté de ne pas toucher à l' selectionSet
non-sens, et il suffit de désélectionner le texte à chaque fois, dans OnGotFocus(), mais alors nous perdrions l'utilisateur de mettre en évidence des onglets en dehors du terrain et à l'arrière.
Laid? Vous betcha. Mais elle est ce qu'elle est.
Les réponses à cette question m'ont beaucoup aidé avec un problème similaire mais la réponse simple n'est qu'indiquée avec beaucoup d'autres suggestions complexes. Il suffit de définir SelectionStart sur 0 après avoir défini votre texte. Problème résolu!
Exemple:
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
Vous pouvez également choisir l'ordre de tabulation pour les contrôles de votre formulaire en ouvrant:
Affichage-> Ordre de tabulation
Notez que cette option est uniquement disponible dans "Affichage" si la vue Conception de formulaire est ouverte.
La sélection de "Ordre de tabulation" ouvre une vue du formulaire qui vous permet de choisir l'ordre de tabulation souhaité en cliquant sur les commandes.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.