Faire en sorte qu'une TextBox WinForms se comporte comme la barre d'adresse de votre navigateur

154

Lorsqu'une zone de texte C # WinForms reçoit le focus, je veux qu'elle se comporte comme la barre d'adresse de votre navigateur.

Pour voir ce que je veux dire, cliquez sur dans la barre d'adresse de votre navigateur Web. Vous remarquerez le comportement suivant:

  1. Cliquer dans la zone de texte devrait sélectionner tout le texte si la zone de texte n'était pas focalisée auparavant.
  2. Faites glisser la souris vers le bas et faites glisser dans la zone de texte pour sélectionner uniquement le texte que j'ai mis en évidence avec la souris.
  3. Si la zone de texte est déjà focalisée, cliquer ne sélectionne pas tout le texte.
  4. La mise au point de la zone de texte par programme ou via la tabulation du clavier doit sélectionner tout le texte.

Je veux faire exactement cela dans WinForms.

ALERTE FASTEST GUN: veuillez lire ce qui suit avant de répondre! Merci les gars. :-)

L'appel de .SelectAll () pendant les événements .Enter ou .GotFocus ne fonctionnera pas car si l'utilisateur a cliqué sur la zone de texte, le curseur sera placé là où il a cliqué, désélectionnant ainsi tout le texte.

L'appel de .SelectAll () pendant l'événement .Click ne fonctionnera pas car l'utilisateur ne pourra pas sélectionner de texte avec la souris; l'appel .SelectAll () continuera d'écraser la sélection de texte de l'utilisateur.

L'appel de BeginInvoke ((Action) textbox.SelectAll) sur focus / enter event enter ne fonctionne pas car il enfreint la règle n ° 2 ci-dessus, il continuera à remplacer la sélection de l'utilisateur sur le focus.

Judah Gabriel Himango
la source
3
Veuillez clarifier ceci est pour un "RichTextBox".
Nescio le
Nescio, une zone de texte ou une zone de texte enrichi fera l'affaire. J'ai également essayé votre solution sur une zone de texte.
Judah Gabriel Himango
C'est une fuite d'abstraction. La meilleure façon de le faire est de marquer WM_MOUSEACTIVATE et SelectAll sur WM_SETFOCUS sinon WM_MOUSEACTIVATE-ing.
wqw
Version WPF: stackoverflow.com/questions/4161531/…
Jonathan Allen

Réponses:

109

Tout d'abord, merci pour les réponses! 9 réponses au total. Je vous remercie.

Mauvaise nouvelle: toutes les réponses avaient des bizarreries ou ne fonctionnaient pas tout à fait correctement (ou pas du tout). J'ai ajouté un commentaire à chacun de vos messages.

Bonne nouvelle: j'ai trouvé un moyen de le faire fonctionner. Cette solution est assez simple et semble fonctionner dans tous les scénarios (souris vers le bas, sélection de texte, mise au point par tabulation, etc.)

bool alreadyFocused;

...

textBox1.GotFocus += textBox1_GotFocus;
textBox1.MouseUp += textBox1_MouseUp;
textBox1.Leave += textBox1_Leave;

...

void textBox1_Leave(object sender, EventArgs e)
{
    alreadyFocused = false;
}


void textBox1_GotFocus(object sender, EventArgs e)
{
    // Select all text only if the mouse isn't down.
    // This makes tabbing to the textbox give focus.
    if (MouseButtons == MouseButtons.None)
    {
        this.textBox1.SelectAll();
        alreadyFocused = true;
    }
}

void textBox1_MouseUp(object sender, MouseEventArgs e)
{
    // Web browsers like Google Chrome select the text on mouse up.
    // They only do it if the textbox isn't already focused,
    // and if the user hasn't selected all text.
    if (!alreadyFocused && this.textBox1.SelectionLength == 0)
    {
        alreadyFocused = true;
        this.textBox1.SelectAll();
    }
}

Pour autant que je sache, cela fait qu'une zone de texte se comporte exactement comme la barre d'adresse d'un navigateur Web.

J'espère que cela aidera le prochain gars qui essaiera de résoudre ce problème d'une simplicité trompeuse.

Merci encore, les gars, pour toutes vos réponses qui m'ont aidé à me diriger vers le bon chemin.

Judah Gabriel Himango
la source
Qu'en est-il lorsque le focus est défini par programme sur une zone de texte? J'ai ce problème comme discuté ici: stackoverflow.com/questions/24790704/ ... J'ai pu le résoudre, d'une certaine manière, mais je suis toujours nerveux à ce sujet, car mon "correctif" semble plutôt dérangeant.
B. Clay Shannon
Vous avez écrit: "L'appel de .SelectAll () pendant les événements .Enter ou .GotFocus ne fonctionnera pas car si l'utilisateur clique sur la zone de texte, le curseur sera placé là où il a cliqué, désélectionnant ainsi tout le texte." J'ai SelectAll dans l'événement GotFocus qui, pour la plupart, fonctionne. En fait, je pense que le curseur placé là où l'utilisateur a cliqué est «une bonne chose». Je veux juste qu'il soit toujours sélectionné lorsque le focus est défini sur la zone de texte par programme.
B. Clay Shannon
Et je suis encore là! :)
dotNET
3
Vous devez déplacer alreadyFocused = true;MouseUp hors de l'instruction if. Parce que si vous sélectionnez immédiatement des parties du texte, le prochain clic sélectionnera à nouveau tout le texte.
Robert S.
Il y a une réponse d'une ligne ci-dessous --- BeginInvoke ((Action) MyTextBox.SelectAll); --- Vaut le détour. Il semble faire tout ce qui est nécessaire
Général Gray
78

J'ai trouvé une solution plus simple à cela. Cela implique de lancer SelectAll de manière asynchrone Control.BeginInvokeafin qu'il se produise après les événements Enter et Click:

En C #:

private void MyTextBox_Enter(object sender, EventArgs e)
{
    // Kick off SelectAll asyncronously so that it occurs after Click
    BeginInvoke((Action)delegate
    {
        MyTextBox.SelectAll();
    });
}

Dans VB.NET (merci à Krishanu Dey )

Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter 
    BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) 
End Sub
Duncan Smart
la source
5
La réponse la plus intelligente que j'ai jamais trouvée .. Merci beaucoup .. Pour VB.net Voici la solution .. Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) End Sub
Krishanu Dey
Classe Much 'Meilleure solution, telle barre d'URL de navigateur Web, beaucoup de classe Fin Classe
ar.dll
7
Dans .Net 4.0, vous pouvez faire: BeginInvoke ((Action) MyTextBox.SelectAll);
JoelFan
2
Malheureusement, BeginInvoke ne fonctionne pas pour moi (sans doute à cause de ma version désastreusement poussiéreuse de Dot net). Prepending "Control". à cela n'aide pas, ni ajouter le nom de la zone de texte elle-même. Seul, et vaguement flânant ...
B. Clay Shannon
2
Notez que cette solution ne se comporte pas exactement comme décrit dans la question. Plus précisément, Mouse down and drag in the textbox should select only the text I've highlighted with the mouse.ne fonctionne pas comme souhaité. Mais toujours la solution la plus courte et la plus élégante :)
Marcus Mangelsdorf
30

Votre solution est bonne, mais échoue dans un cas précis. Si vous donnez le focus à TextBox en sélectionnant une plage de texte au lieu de simplement cliquer, l'indicateur alreadyFocussed n'est pas défini sur true, donc lorsque vous cliquez une deuxième fois dans la zone de texte, tout le texte est sélectionné.

Voici ma version de la solution. J'ai également mis le code dans une classe qui hérite de TextBox, donc la logique est bien cachée.

public class MyTextBox : System.Windows.Forms.TextBox
{
    private bool _focused;

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        if (MouseButtons == MouseButtons.None)
        {
            SelectAll();
            _focused = true;
        }
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        _focused = false;
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        base.OnMouseUp(mevent);
        if (!_focused)
        {
            if (SelectionLength == 0)
                SelectAll();
            _focused = true;
        }
    }
}
Nzhenry
la source
2
+1 pour une suggestion de zone de texte personnalisée et une solution parfaitement fonctionnelle!
Ravitaillé
Excellente solution. J'ai copié votre code directement dans ma solution, modifié l'espace de noms pour protéger les innocents et a parfaitement fonctionné. Merci!
kenswdev
8

C'est un peu kludgey, mais dans votre événement de clic, utilisez SendKeys.Send( "{HOME}+{END}" );.

Todd Benning
la source
Woofta! C'est un peu du piratage! :-) Merci pour la suggestion. De meilleures idées?
Judah Gabriel Himango
Hacking en effet, mais cela ne sonne pas mal du tout
Terry
3
Considérez que de nombreux programmes anti-virus interceptent et bloquent SEND KEYS comme malveillants. Ce n'est pas une excellente solution.
Judah Gabriel Himango
4

Cliquez sur l'événement de la zone de texte? Ou même l'événement MouseCaptureChanged fonctionne pour moi. - D'ACCORD. ne fonctionne pas.

Vous devez donc faire 2 choses:

private bool f = false;

private void textBox_MouseClick(object sender, MouseEventArgs e)
{ 
  if (this.f) { this.textBox.SelectAll(); }
  this.f = false;
}

private void textBox_Enter(object sender, EventArgs e)
{
  this.f = true;
  this.textBox.SelectAll();
}
private void textBox_MouseMove(object sender, MouseEventArgs e) // idea from the other answer
{
  this.f = false; 
}

Fonctionne également pour la tabulation (via textBoxes vers celui-ci) - appelez SelectAll () dans Enter juste au cas où ...

Jakub Kotrla
la source
Ok Jakub, ça marche partiellement. Si je tabule vers la zone de texte, elle doit se concentrer. Cela fonctionnera-t-il avec votre solution? (Si vous pouvez me montrer comment, je marquerai votre réponse comme la bonne réponse.)
Judah Gabriel Himango
Jakub, maintenant que vous avez publié le code, il semble parfois fonctionner. Pas toujours; en ce moment, je clique dans la zone de texte et je ne sélectionne pas tout.
Judah Gabriel Himango
Parfois, je clique dans le texte et il ne sélectionne pas tout. C'est comme si le champ .f n'était pas défini sur ce qu'il devrait être, puis SelectAll ne sera pas appelé. Vous n'avez pas vu ça?
Judah Gabriel Himango
Je sais seulement que grâce à mouseMouve, vous pouvez cliquer lentement tout en déplaçant la souris (en particulier sur les lettres larges) -> désactiver le drapeau. Vous pouvez supprimer le code dans l'événement mouseMove, mais que vous obtenez - après tabbgin pour contrôler puis en cliquant - reSelectAll - impossible de sélectionner une partie de l'agitation lors du premier glissement
Jakub Kotrla
4

Une réponse en une ligne que j'utilise ... vous pourriez vous donner un coup de pied ...

Dans l'événement Enter:

txtFilter.BeginInvoke (nouveau MethodInvoker (txtFilter.SelectAll));


la source
1
Non, ça ne marche pas. Il sélectionne tout le texte, d'accord, mais il empêche également l'utilisateur de ne sélectionner qu'une partie du texte, entre autres problèmes.
Judah Gabriel Himango le
Désolé, j'ai dû mal comprendre le comportement que vous recherchiez. En entrant, il sélectionne tout, si vous cliquez et maintenez-le, sélectionnez du début à votre curseur. Je suppose que vous pouvez utiliser ce que j'ai et remplacer SelectAll par votre propre logique de sélection. notifywire.com/demos/2009-04-14_1248.swf
Fonctionne très bien! Le premier clic entre dans la boîte; puis cliquez et faites glisser pour sélectionner du texte.
D_Bester
Remarque: cela ne fonctionne pas comme la barre d'adresse d'un navigateur Web. La barre d'adresse d'un navigateur Web vous permet de faire glisser la souris vers le bas dans la zone de texte et de faire glisser / sélectionner, même lorsque la zone de texte n'a pas encore le focus. Cette solution ne résout pas cela. Si cela vous convient, cool, mais cela ne répond pas aux exigences de cette question.
Judah Gabriel Himango
3
'Inside the Enter event
TextBox1.SelectAll();

Ok, après l'avoir essayé, voici ce que vous voulez:

  • Sur l'événement Enter, démarrez un indicateur indiquant que vous avez participé à l'événement Enter
  • Sur l'événement Click, si vous définissez l'indicateur, appelez .SelectAll () et réinitialisez l'indicateur.
  • Lors de l'événement MouseMove, définissez l'indicateur saisi sur false, ce qui vous permettra de cliquer sur la mise en évidence sans avoir à entrer d'abord dans la zone de texte.

Cela a sélectionné tout le texte sur l'entrée, mais m'a permis de mettre en évidence une partie du texte par la suite, ou vous permet de mettre en évidence au premier clic.

Sur demande:

    bool entered = false;
    private void textBox1_Enter(object sender, EventArgs e)
    {
        entered = true;
        textBox1.SelectAll();   //From Jakub's answer.
    }

    private void textBox1_Click(object sender, EventArgs e)
    {
        if (entered) textBox1.SelectAll();
        entered = false;
    }

    private void textBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (entered) entered = false;
    }

Pour moi, la tabulation dans le contrôle sélectionne tout le texte.

MagicKat
la source
Votre solution est similaire à la solution de Jakub. Cela fonctionne pour cliquer. Peut-il fonctionner lors de la tabulation dans la zone de texte? (Par exemple, si vous accédez à la barre d'adresse de votre navigateur, vous sélectionnez également tout le texte.)
Judah Gabriel Himango
Oui, cela fonctionne aussi pour la tabulation. J'ai écrit une application de test et c'est ainsi que je l'ai fait fonctionner.
MagicKat
Ne semble pas fonctionner pour la tabulation. Pouvez-vous nous montrer le code qui fonctionne pour la tabulation?
Judah Gabriel Himango
3

Voici une fonction d'assistance qui amène la solution au niveau suivant - réutilisation sans héritage.

    public static void WireSelectAllOnFocus( TextBox aTextBox )
    {
        bool lActive = false;
        aTextBox.GotFocus += new EventHandler( ( sender, e ) =>
        {
            if ( System.Windows.Forms.Control.MouseButtons == MouseButtons.None )
            {
                aTextBox.SelectAll();
                lActive = true;
            }
        } );

        aTextBox.Leave += new EventHandler( (sender, e ) => {
            lActive = false;
        } );

        aTextBox.MouseUp += new MouseEventHandler( (sender, e ) => {
            if ( !lActive )
            {
                lActive = true;
                if ( aTextBox.SelectionLength == 0 ) aTextBox.SelectAll();
            }   
        });
    }

Pour l'utiliser, appelez simplement la fonction en passant une zone de texte et elle s'occupe de tous les bits désordonnés pour vous. Je suggère de câbler toutes vos zones de texte dans l'événement Form_Load. Vous pouvez placer cette fonction dans votre formulaire, ou si vous êtes comme moi, quelque part dans une classe utilitaire pour encore plus de réutilisation.

Ross K.
la source
2

Cela a fonctionné pour une TextBox WPF / XAML.

    private bool initialEntry = true;
    private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
    {
        if (initialEntry)
        {
            e.Handled = true;
            initialEntry = false;
            TextBox.SelectAll();
        }
    }
    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox.SelectAll();
        initialEntry = true;      
    }
slobs
la source
2

Ceci est similaire à la réponse populaire de nzhenry , mais je trouve qu'il est plus facile de ne pas avoir à sous-classer:

Private LastFocused As Control = Nothing

Private Sub TextBox1_Enter(sender As Object, e As System.EventArgs) Handles TextBox1.Enter, TextBox2.Enter, TextBox3.Enter
    If MouseButtons = Windows.Forms.MouseButtons.None Then LastFocused = sender
End Sub

Private Sub TextBox1_Leave(sender As Object, e As System.EventArgs) Handles TextBox1.Leave, TextBox2.Leave, TextBox3.Leave
    LastFocused = Nothing
End Sub

Private Sub TextBox1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseUp, TextBox2.MouseUp, TextBox3.MouseUp
    With CType(sender, TextBox)
        If LastFocused IsNot sender AndAlso .SelectionLength = 0 Then .SelectAll()
    End With
    LastFocused = sender
End Sub
Chris
la source
1

SelectAll n'a jamais fonctionné pour moi.

Cela marche.

ActiveControl = textBox1;
textBox1->SelectionStart = 0;
textBox1->SelectionLength = textBox1->Text->Length;
Adam Bruss
la source
Cela ne tient pas compte du cas où la tabulation dans la zone de texte apporte le focus. Il présente également certains des autres problèmes abordés dans ce fil.
Judah Gabriel Himango
1

J'ai trouvé une solution encore plus simple:

Pour vous assurer que tout le texte est sélectionné lorsque vous cliquez sur une zone de texte, assurez-vous que le gestionnaire Click appelle le gestionnaire Enter. Pas besoin de variables supplémentaires!

Exemple:

private void textBox1_Click(object sender, EventArgs e){
        textBox1_Enter(sender, e);
    }

private void textBox1_Enter(object sender, EventArgs e){
        TextBox tb = ((TextBox)sender);
        tb.SelectAll();
    }
Pieter Heemeryck
la source
Cela ne fonctionne pas pour le focus via la tabulation dans le contrôle, non? Aussi, qu'en est-il lorsque vous souhaitez sélectionner du texte sans tout sélectionner?
Judah Gabriel Himango
En fait, cela fonctionne avec la tabulation! Je viens de le tester dans un projet factice à l'aide de MS Visual C # 2010. La chose ennuyeuse avec cette solution est que vous ne pouvez pas sélectionner du texte sans tout sélectionner. Si vous voulez faire juste cela, aucun code n'est nécessaire bien sûr, vous pouvez simplement utiliser votre souris et le sélectionner (ou en utilisant le clavier).
Pieter Heemeryck
Et c'est pourquoi cette solution ne résout pas le problème présenté: elle ne se comporte pas comme la zone d'adresse du navigateur, car vous ne pouvez pas cliquer sur des parties individuelles de l'adresse sans sélectionner tout le texte.
Judah Gabriel Himango
Ok, je vois ce que tu veux dire. Le titre de la question et l'exemple de barre d'adresse du navigateur Web n'indiquaient pas que vous devriez être en mesure de sélectionner une partie du texte. Vous ne l'avez mentionné que dans la dernière phrase de votre question. Cordialement.
Pieter Heemeryck
0
private bool _isSelected = false;
private void textBox_Validated(object sender, EventArgs e)
{
    _isSelected = false;
}

private void textBox_MouseClick(object sender, MouseEventArgs e)
{
    SelectAllText(textBox);
}

private void textBox_Enter(object sender, EventArgs e)
{
    SelectAllText(textBox);
}

private void SelectAllText(TextBox text)
{
    if (!_isSelected)
    {
        _isSelected = true;
        textBox.SelectAll();
    }
}
Nescio
la source
Je viens de tester avec un RichTextBox. Ça ne marche pas. Cliquer dans la zone de texte n'apparaît pas pour sélectionner tout le texte. (Parce qu'il est désélectionné lorsque la souris est enfoncée, lorsque le curseur est placé sur le curseur.)
Judah Gabriel Himango
0

Fait intéressant, un ComboBox avec DropDownStyle = Simple a à peu près exactement le comportement que vous recherchez, je pense.

(Si vous réduisez la hauteur du contrôle pour ne pas afficher la liste - puis de quelques pixels de plus - il n'y a pas de différence effective entre le ComboBox et le TextBox.)


la source
Intéressant, mais j'en ai vraiment besoin pour travailler sur TextBox et RichTextBox.
Judah Gabriel Himango
0

Pourquoi n'utilisez-vous pas simplement l'événement MouseDown de la zone de texte? Cela fonctionne bien pour moi et n'a pas besoin d'un booléen supplémentaire. Très propre et simple, par exemple:

private void textbox_MouseDown(object sender, MouseEventArgs e) {
    if (textbox != null && !string.IsNullOrEmpty(textbox.Text))
    {
        textbox.SelectAll();
    } }

la source
Non, quelques problèmes avec ceci: ne tient pas compte si la zone de texte a déjà le focus (nous ne voulons pas sélectionner-tout chaque souris enfoncée, juste lorsque la zone de texte n'a pas le focus), ne vous permet pas de sélectionner uniquement une partie du texte, ne fonctionne pas lorsque vous mettez le focus via la tabulation dans la zone de texte.
Judah Gabriel Himango
0

J'ai appelé SelectAll à l'intérieur de l'événement MouseUp et cela a bien fonctionné pour moi.

    private bool _tailTextBoxFirstClick = false;

    private void textBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if(_textBoxFirstClick)           
            textBox1.SelectAll();

        _textBoxFirstClick = false;
    }  

    private void textBox1_Leave(object sender, EventArgs e)
    {
        _textBoxFirstClick = true;
        textBox1.Select(0, 0);
    }
Sreejith K.
la source
Ouais, voyez les autres réponses (et commentaires) pour savoir pourquoi cela ne fonctionne pas dans tous les scénarios.
Judah Gabriel Himango
Je n'ai pas vérifié l'onglet pour cette solution. Ma faute. Merci de l'avoir signalé. Heureux de voir que vous avez la solution complète maintenant. Et aussi heureux de savoir que ma suggestion pour MouseUp a été incluse dans votre solution.
Sreejith K.
0

Dérivez simplement une classe de TextBox ou MaskedTextBox:

public class SMaskedTextBox : MaskedTextBox
{
    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        this.SelectAll();
    }
}

Et utilisez-le sur vos formulaires.

Mohammad Mahdipour
la source
Cela ne marche pas. Pour comprendre pourquoi, consultez les autres réponses et commentaires.
Judah Gabriel Himango
0

En fait, GotFocus est le bon événement (message vraiment) qui vous intéresse, car peu importe comment vous obtenez le contrôle, vous l'obtiendrez même éventuellement. La question est de savoir quand appelez-vous SelectAll ().

Essaye ça:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.textBox1.GotFocus += new EventHandler(textBox1_GotFocus);
    }

    private delegate void SelectAllDelegate();    
    private IAsyncResult _selectAllar = null; //So we can clean up afterwards.

    //Catch the input focus event
    void textBox1_GotFocus(object sender, EventArgs e)
    {
        //We could have gotten here many ways (including mouse click)
        //so there could be other messages queued up already that might change the selection.
        //Don't call SelectAll here, since it might get undone by things such as positioning the cursor.
        //Instead use BeginInvoke on the form to queue up a message
        //to select all the text after everything caused by the current event is processed.
        this._selectAllar = this.BeginInvoke(new SelectAllDelegate(this._SelectAll));
    }

    private void _SelectAll()
    {
        //Clean-up the BeginInvoke
        if (this._selectAllar != null)
        {
            this.EndInvoke(this._selectAllar);
        }
        //Now select everything.
        this.textBox1.SelectAll();
    }
}
Peter Mortensen
la source
Ali, ça ne marche pas. Essayez de passer la souris au milieu du texte. Maintenez le bouton de la souris enfoncé pendant 1 seconde.
Judah Gabriel Himango
0

Pour un groupe de zones de texte dans un formulaire:

private System.Windows.Forms.TextBox lastFocus;   

private void textBox_GotFocus(object sender, System.Windows.Forms.MouseEventArgs e)   
{
    TextBox senderTextBox = sender as TextBox;
    if (lastFocus!=senderTextBox){
        senderTextBox.SelectAll();
    }
    lastFocus = senderTextBox;   
}
Yfiua
la source
1
Cela ne fonctionne pas correctement; voir mes réponses aux autres réponses suggérant .SelectAll (). Cela ne fonctionne pas car si vous entrez dans la zone de texte tout en essayant de sélectionner du texte, cela interrompt votre sélection de texte en sélectionnant tout le texte. Vous ne voulez sélectionner du texte que si le focus est entré dans la zone de texte via la souris vers le haut ou par tabulation, mais si le focus a été causé via la souris vers le bas.
Judah Gabriel Himango
0

Je sais que cela a déjà été résolu, mais j'ai une suggestion qui, à mon avis, est en fait plutôt simple.

Dans l'événement de la souris, tout ce que vous avez à faire est de placer

if(textBox.SelectionLength = 0)
{
    textBox.SelectAll();
}

Cela semble fonctionner pour moi dans VB.NET (je sais que c'est une question C # ... malheureusement, je suis obligé d'utiliser VB à mon travail .. et j'avais ce problème, c'est ce qui m'a amené ici ... )

Je n'ai pas encore trouvé de problème avec ça ... sauf le fait qu'il ne sélectionne pas immédiatement au clic, mais j'avais des problèmes avec ça ....

Eluem
la source
1
La demande d'origine voulait que cela fonctionne également lorsque vous accédez au champ.
Don Kirkby
2
Oui, cela ne fonctionne pas pour tous les scénarios. Cela ne fonctionne que lorsque vous cliquez dans la zone de texte. Et même dans ce cas, si ne se comporte pas comme une barre d'adresse de navigateur se comporte lorsque la sélection existe déjà dans la zone de texte.
Judah Gabriel Himango
0

La solution suivante fonctionne pour moi. J'ai ajouté OnKeyDownet OnKeyUpoverride d'événements pour conserver le texte TextBox toujours sélectionné.

    public class NumericTextBox : TextBox
{
    private bool _focused;
    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        if (MouseButtons == MouseButtons.None)
        {
            this.SelectAll();
            _focused = true;
        }
    }
    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        if (MouseButtons == MouseButtons.None)
        {
            SelectAll();
            _focused = true;
        }
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        _focused = false;
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        base.OnMouseUp(mevent);
        if (!_focused)
        {
            if (SelectionLength == 0)
                SelectAll();
            _focused = true;
        }
    }

    protected override void OnKeyUp(KeyEventArgs e)
    {
        base.OnKeyUp(e);

        if (SelectionLength == 0)
            SelectAll();
        _focused = true;
    }
    protected override void OnKeyDown(KeyEventArgs e)
    {
       base.OnKeyDown(e);
       if (SelectionLength == 0)
            SelectAll();
        _focused = true;
    }
}
abrfra
la source
2
Cela vous permet-il de faire glisser la souris vers le bas dans la zone de texte, de faire glisser votre curseur pour sélectionner du texte, puis de faire glisser la souris vers le haut?
Judah Gabriel Himango
0

Définissez la sélection lorsque vous quittez le contrôle. Il sera là à votre retour. Tabulation autour du formulaire et lorsque vous revenez au contrôle, tout le texte sera sélectionné.

Si vous entrez avec la souris, le curseur sera correctement placé à l'endroit où vous avez cliqué.

private void maskedTextBox1_Leave(object sender, CancelEventArgs e)
    {
        maskedTextBox1.SelectAll();
    }
Joël
la source
Si vous entrez avec la souris, il devrait sélectionner tout le texte, à moins qu'il ne soit déjà focalisé. Cela ne supporte pas cela.
Judah Gabriel Himango
0

Solution très simple:

    private bool _focusing = false;

    protected override void OnEnter( EventArgs e )
    {
        _focusing = true;
        base.OnEnter( e );
    }

    protected override void OnMouseUp( MouseEventArgs mevent )
    {
        base.OnMouseUp( mevent );

        if( _focusing )
        {
            this.SelectAll();
            _focusing = false;
        }
    }

EDIT: Original OP était en particulier préoccupé par la séquence souris vers le bas / sélection de texte / souris vers le haut, auquel cas la solution simple ci-dessus aboutirait à une sélection partielle du texte.

Cela devrait résoudre * le problème (en pratique j'intercepte WM_SETCURSOR):

    protected override void WndProc( ref Message m )
    {
        if( m.Msg == 32 ) //WM_SETCURSOR=0x20
        {
              this.SelectAll(); // or your custom logic here                
        }

        base.WndProc( ref m );
    }

* En fait, la séquence suivante se termine par une sélection de texte partielle, mais si vous déplacez la souris sur la zone de texte, tout le texte sera à nouveau sélectionné:

mouse-down / text-selection / mouse-move-out-textbox / mouse-up

Mauro Sampietro
la source
Cette solution était déjà postée. Consultez le commentaire de la réponse existante pour savoir pourquoi cela ne fonctionne pas.
Judah Gabriel Himango
fonctionne avec l'onglet et avec la souris, vous pouvez obtenir le focus, sélectionner du texte, puis la souris. Je n'arrive pas à trouver le problème avec ça. Pouvez-vous le souligner?
Mauro Sampietro le
0

Je trouve que cela fonctionne mieux, lorsque la souris clique et ne relâche pas immédiatement:

    private bool SearchBoxInFocusAlready = false;
    private void SearchBox_LostFocus(object sender, RoutedEventArgs e)
    {
        SearchBoxInFocusAlready = false;
    }

    private void SearchBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (e.ButtonState == MouseButtonState.Released && e.ChangedButton == MouseButton.Left &&
            SearchBox.SelectionLength == 0 && SearchBoxInFocusAlready == false)
        {
            SearchBox.SelectAll();
        }

        SearchBoxInFocusAlready = true;
    }
user3729779
la source
0

Ma solution est assez primitive mais fonctionne bien pour mon objectif

private async void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (sender is TextBox)
    {
        await Task.Delay(100);
        (sender as TextBox).SelectAll();
    }
}
BlueWizard
la source
Ne fonctionne pas lorsque vous souhaitez faire glisser la souris vers le bas pour sélectionner un groupe de texte, faire glisser votre souris, puis la souris vers le haut. Votre code effacera la sélection et sélectionnera tout.
Judah Gabriel Himango
@JudahHimango Jup. Si vous cliquez une seule fois, tout sélectionnera. Si vous cliquez et faites glisser, il sélectionnera uniquement la sélection. Au moins, la barre de navigation de Firefox montre exactement ce comportement.
BlueWizard
n'est-ce pas une condition de course? Si je parviens à sélectionner rapidement du texte avec la souris, le .SelectAll () se déclenchera quelques millisecondes plus tard, écrasant ma sélection.
Judah Gabriel Himango
1
Ok, si vous choisissez rapidement les choses, cette chose fonctionnera contre vous.
BlueWizard
-1

Le ci-dessous semble fonctionner. L'événement enter gère la tabulation vers le contrôle et MouseDown fonctionne lorsque l'utilisateur clique sur le contrôle.

    private ########### void textBox1_Enter(object sender, EventArgs e)
    {
        textBox1.SelectAll();
    }

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (textBox1.Focused)
            textBox1.SelectAll();
    }
benPearce
la source
Pas de chance, ça ne marche pas, j'ai peur. Essayez de sélectionner du texte. Le texte .SelectAll écrase ce que l'utilisateur tente de sélectionner.
Judah Gabriel Himango
-1

La réponse peut être en fait bien plus simple que TOUT ce qui précède, par exemple (dans WPF):

public void YourTextBox_MouseEnter(object sender, MouseEventArgs e)
    {
        YourTextBox.Focus();
        YourTextBox.SelectAll();
    }

bien sûr, je ne peux pas savoir comment vous voulez utiliser ce code, mais la partie principale à regarder ici est: Appelez d'abord .Focus () puis appelez .SelectAll ();

MDB
la source
Cela ne fonctionne pas et est une copie d'autres réponses. Par exemple, si vous déplacez la souris vers le bas dans la zone de texte, faites glisser, il doit sélectionner une partie du texte. Cela brise cela et ne sélectionne pas tout.
Judah Gabriel Himango
-1

utilisez simplement selectall () lors de l'entrée et cliquez sur les événements

private void textBox1_Enter(object sender, EventArgs e)
        {

            textBox1.SelectAll();
        }
        private void textBox1_Click(object sender, EventArgs e)
        {
            textBox1.SelectAll();
        }
EKanadily
la source
Cela fonctionne jusqu'à ce que vous souhaitiez sélectionner du texte. Voir les autres réponses pour une explication complète.
Judah Gabriel Himango
-1

J'ai créé un nouveau projet VB.Net Wpf. J'ai créé une TextBox et utilisé ce qui suit pour le codebehind:

Class MainWindow 

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        AddHandler PreviewMouseLeftButtonDown, New MouseButtonEventHandler(AddressOf SelectivelyIgnoreMouseButton)
        AddHandler GotKeyboardFocus, New KeyboardFocusChangedEventHandler(AddressOf SelectAllText)
        AddHandler MouseDoubleClick, New MouseButtonEventHandler(AddressOf SelectAllText)
    End Sub

    Private Shared Sub SelectivelyIgnoreMouseButton(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        ' Find the TextBox
        Dim parent As DependencyObject = TryCast(e.OriginalSource, UIElement)
        While parent IsNot Nothing AndAlso Not (TypeOf parent Is TextBox)
            parent = VisualTreeHelper.GetParent(parent)
        End While

        If parent IsNot Nothing Then
            Dim textBox As Object = DirectCast(parent, TextBox)
            If Not textBox.IsKeyboardFocusWithin Then
                ' If the text box is not yet focussed, give it the focus and
                ' stop further processing of this click event.
                textBox.Focus()
                e.Handled = True
            End If
        End If
    End Sub

    Private Shared Sub SelectAllText(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim textBox As Object = TryCast(e.OriginalSource, TextBox)
        If textBox IsNot Nothing Then
            textBox.SelectAll()
        End If
    End Sub

End Class
BSalita
la source