2010-03-09 6 views
6

J'ai un programme Winforms C# avec plusieurs zones de texte. J'ai utilisé les propriétés de chaque boîte pour y placer du texte, expliquant à l'utilisateur quelle valeur y entre. Je souhaite que le texte soit mis en surbrillance chaque fois qu'un utilisateur sélectionne cette case. Par tabulation ou clic de souris. Je n'aurai pas à faire cela s'il y a un moyen d'afficher quelle valeur va dans la zone de texte quelque part en dehors de celui-ci.Comment mettre en surbrillance le texte dans une zone de texte dans un programme Winforms C#?

J'ai essayé la méthode Textbox.select mais elle n'a eu aucun effet. La même chose avec this. Voici un Screenshot de mon programme.

Mon code:

private void grapplingText1_MaskInputRejected(object sender, MaskInputRejectedEventArgs e) 
    { 
     grapplingText1.SelectionStart = 0; 
     grapplingText1.SelectionLength = grapplingText1.Text.Length; 

Est-ce que cela, ou est plus nécessaire?

+0

Si vous avez essayé deux solutions ... la deuxième * devrait * avoir fonctionné ... cela pourrait être un bug dans le code. Pourriez-vous s'il vous plaît fournir le code que vous avez réellement utilisé? – Nick

+0

J'ai posté le code. Faites-moi savoir si c'est suffisant pour continuer. – Slateboard

+0

Alors, est-ce qu'une solution vous a aidé avec ce que vous vouliez accomplir? – MadBoy

Répondre

8

Que diriez-vous d'attribuer ToolTip à TextBox et de mettre tous les "parler quoi textbox est pour" à l'intérieur de cela? Il suffit de faire glisser & déposer ToolTip à l'intérieur du formulaire Et puis dans chaque TextBox propriétés, vous devriez avoir une entrée supplémentaire dans la section Misc ToolTip sur toolTip1 (ou quel que soit son nom sera si vous le renommez).

Ensuite, lorsque l'utilisateur survole TextBox (lecture seule/désactivé TextBox ne semble pas afficher les info-bulles) et s'arrête là pendant 1 seconde ToolTip devrait montrer avec les informations appropriées.

Vous pouvez éventuellement ou même mieux d'avoir un Label à côté de TextBox dire ce qui est est, mais ayant un ToolTip est aussi une bonne idée d'expliquer plus d'informations à l'utilisateur à travers cela.

Pour faire des choses avec WaterMark afin de ne pas avoir à aller loin en définissant les événements, en prenant soin de SelectAll etc, vous pouvez le faire comme ça. Créez un nouveau fichier watermark.cs et remplacez-le par ce code. Assurez-vous que vous avez changé d'espace de noms pour correspondre à votre espace de nom de programme.

#region 
using System; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

#endregion 

namespace Watermark { 
    public static class TextBoxWatermarkExtensionMethod { 
     private const uint ECM_FIRST = 0x1500; 
     private const uint EM_SETCUEBANNER = ECM_FIRST + 1; 
     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); 
     public static void SetWatermark(this TextBox textBox, string watermarkText) { 
      SendMessage(textBox.Handle, EM_SETCUEBANNER, 0, watermarkText); 
     } 
    } 
} 
    internal class WatermarkTextBox : TextBox { 
    private const uint ECM_FIRST = 0x1500; 
    private const uint EM_SETCUEBANNER = ECM_FIRST + 1; 
    private string watermarkText; 
    public string WatermarkText { 
     get { return watermarkText; } 
     set { 
      watermarkText = value; 
      SetWatermark(watermarkText); 
     } 
    } 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); 
    private void SetWatermark(string watermarkText) { 
     SendMessage(Handle, EM_SETCUEBANNER, 0, watermarkText); 
    } 
} 

Dans votre formulaire vous activez comme ceci:

textBoxYourWhatever.SetWatermark("Text that should display"); 

Il y reste aussi longtemps le TextBox est vide. Lorsque les utilisateurs entrent dans TextBox le texte disparaît. Il apparaît à nouveau lorsque TextBox est nettoyé (par l'utilisateur ou automatiquement). Pas besoin d'événements spéciaux, etc.

EDIT:

J'ai ajouté aussi WaterMarkTextBox de classe interne qui vous donne la possibilité d'utiliser simplement nouvelle WaterMarkTexBox qui devient disponible dans Designer. Ensuite, faites-le glisser et déposez-le à votre concepteur et utilisez-le. Il se comporte comme un champ de texte normal et vous donne juste un champ supplémentaire WaterMarkText. Je préfère toujours la première méthode. Ne te fait pas reconstruire ton gui.

+0

+1 Je vais garder votre exemple, je le trouve très utile =) – Javier

+0

Je l'ai essayé et l'erreur que je me suis dit: Les méthodes d'extension doivent être définies dans une classe statique de premier niveau; TextBoxWatermarkExtensionMethod est une classe imbriquée Qu'est-ce que je fais mal? En outre, .SetWatermark n'est pas répertorié sur la saisie semi-automatique. – Slateboard

+0

Je devine, à partir de cette erreur, que vous avez mis la classe Extensions à l'intérieur d'une autre classe. Tu ne peux pas faire ça. Ce doit être une classe de haut niveau. Une fois que vous faites cela, et qu'il compile, alors SetWatermark apparaîtra dans l'IntelliSense. –

7

Je pense que .select fonctionnera si vous connaissez la quantité de texte que vous voulez sélectionner.

Essayez .SelectAll(); Il devrait fonctionner pour vous

3

Vous devez utiliser le TextBox.Focus() pour obtenir le focus sur votre contrôle, et si ne fonctionne pas automatiquement, appelez simplement la méthode SelectAll() sur l'événement Enter().

private TextBox1_Enter(object sender, EventArgs e) {  
    TextBoxTextHighlight(sender, null); 
} 

private TextBox2_Enter(object sender, EventArgs e) { 
    TextBoxTextHighlight(sender, null); 
} 

private TextBox3_Enter(object sender, EventArgs e) { 
    TextBoxTextHighlight(sender, null); 
} 

// And so forth... 

private void TextBoxTextHighlight(object sender, EventArgs e) { 
    (sender as TextBox).SelectAll(); 
} 

Cette méthode vous permettra de l'appeler à partir de n'importe quel gestionnaire d'événements TextBoxX_Enter(). Sinon, vous pouvez même créer un nouveau UserControl, l'appeler comme vous le souhaitez lors de la création, puis, lorsqu'il est créé dans votre projet, éditer le code et remplacer l'héritage de la classe UserControl par la classe TextBox, puis définir en son sein comportement par défaut que vous souhaitez avoir sur la touche Entrée() événement, comme cet appel à la méthode SelectAll(), et le rendre protégé virtuel et dans le constructeur, vous pouvez souscrire le gestionnaire d'événements comme ceci:

public partial class CustomTextBox : TextBox { 
    public CustomTextBox() 
     : base() { 
     this.Enter += new EventHandler(Enter); 
    } 

    protected virtual Enter(object sender, EventArgs e) { 
     this.SelectAll(); 
    } 
} 

Je l'ai écrit à la volée, alors peut-être que quelques modifications sont nécessaires, mais vous pouvez avoir l'idée. Mais je ne vous conseille pas de le faire à moins que ce ne soit vraiment digne de le faire pour votre situation. Le plus simple sera le mieux, et le plus simple est de créer un gestionnaire d'événements pour chacune des TextBoxes de votre formulaire, puis d'appeler la méthode TextBoxTextHighlight().

+0

Je fais cela pour chaque zone de texte? – Slateboard

+0

Double-cliquer sur l'événement Enter() de la liste des événements de la fenêtre de propriétés pour chaque TextBox vous permettra d'écrire la ligne de code dans le gestionnaire d'événements TextBox1_Enter() et de propager la fonctionnalité de SelectAll() sans trop d'efforts. Alors oui, pour chaque TextBox. –

2

Supposons que votre nom de textbox's est « MyTextBox »

Vous pouvez écrire la méthode pour gérer l'événement de mise au point:

private void MyTextBox_GotFocus(object sender, EventArgs e) 
{ 
    MyTextBox.SelectionStart = 0; 
    MyTextBox.SelectionLength = MyTextBox.Text.Length; 
    MyTextBox.Select(); 
} 

besoin d'ajouter vous en aurez aussi le gestionnaire d'événements:

this.MyTextBox.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus); 

Cela devrait fonctionner ...

EDIT

Vous pouvez utiliser la même méthode pour les autres zone de texte, ajoutez simplement le gestionnaire d'événements:

this.MyTextBox2.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus); 
this.MyTextBox3.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus); 
this.MyTextBox4.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus); 
//... 
+0

Remplace-t-il le code déjà entré? – Slateboard

+0

Oui, au moins, j'ai fait un test avec ce code, et ça marche bien =) – Javier

+0

Je remplace toutes les instances de mytextbox par les noms de mes boîtes de texte, n'est-ce pas? – Slateboard

2

En règle générale, si vous voulez expliquer à l'utilisateur ce qui se passe dans une zone de texte, vous placez un contrôle Label directement au-dessus, (ou sur le côté).

Parfois, cependant, pour sauver l'écran immobilier, vous pouvez mettre une description du texte à l'intérieur de la zone de texte elle-même. C'est ce qu'on appelle un watermark.

+0

Eh bien, les zones de texte affichent actuellement des descriptions de texte en leur sein, est-ce que c'est ce que vous voulez dire par un filigrane? – Slateboard

+0

Le filigrane est comme un texte intégré que vous n'aurez pas à prendre en compte lorsque l'utilisateur tentera de saisir des données dans ce TextBox. Il apparaît toujours quand TextBox est vide, et il est parti quand il y a Text Inside. – MadBoy

+0

Droite. Un bon exemple de filigrane est la zone de texte de recherche en haut à droite de stackoverflow. L'inconvénient du filigrane est que vous ne pouvez pas dire ce que la valeur est censée signifier quand il est rempli. En regardant votre capture d'écran, je vous recommande d'utiliser les contrôles Label, placés directement au-dessus des zones de texte. –

0

La façon la plus simple d'afficher des informations supplémentaires en survolant un élément consiste à utiliser une info-bulle. J'ai essayé une approche de filigrane similaire, mais ayant trouvé qu'il n'y avait pas de moyen immédiat de l'implémenter, l'info-bulle semblait être une alternative appropriée.

Vous pouvez voir comment la mettre en œuvre sur le lien suivant: Implementing a tooltip

+0

Vérifiez ma réponse pour mettre en œuvre le filigrane de manière immédiate Facile à mettre en œuvre et à utiliser – MadBoy

+0

Impressionnant, beau travail. –

-1

J'ai trouvé que dans ma demande, fixant la méthode de mise en évidence à la mise au point -> Entrée événement n'a pas bien fonctionné avec le SelectAll() méthode. J'ai plutôt utilisé Action -> Click (que je crois ne fonctionne que pour les souris) et attaché ma méthode de mise en évidence là. Maintenant, cela fonctionne comme un charme.

Questions connexes