2008-09-05 10 views
9

Je travaille sur une application Winforms C# (VS.NET 2008, .NET 3.5 sp 1). J'ai un champ de recherche sur un formulaire, et plutôt que d'avoir une étiquette à côté du champ de recherche, j'aimerais afficher un texte gris en arrière-plan du champ de recherche lui-même ('Termes de recherche', par exemple). Lorsque l'utilisateur commence à entrer du texte dans le champ de recherche, le texte devrait disparaître. Comment puis-je atteindre cet objectif?Affichage d'un indice pour un contrôle d'édition winforms C#

Répondre

9

Pour ce faire, vous devrez utiliser un code d'interopérabilité P/Inovke. Recherchez la fonction Win32 API SendMessage et le message EM_SETCUEBANNER.

0

Il existe une fonctionnalité intégrée dans le champ de saisie de texte - AutoCompleteMode et AutoCompleteSource. Ils peuvent valoir la peine d'essayer avant d'entrer dans les contrôles personnalisés ou de tiers.

2

Je pense que la façon dont cela se fait généralement est de définir la couleur du texte gris et préremplir avec le texte de votre indice.

Ensuite, écrivez des gestionnaires pour les événements de focus du champ de texte, en modifiant le contenu des champs et la couleur en fonction du gain et de la perte de focus. Voici quelques pseudo-code (désolé, il est tout à fait pas du code C# J'ai Actionscript sur le cerveau en ce moment.):

TextInput myInput; 
boolean showingHint = true; 

myInput.text = "Search Terms"; 
myInput.color = 0xcccccc; 

myInput.onFocusGained = function() { 
    if(showingHint) { 
    myInput.text = ""; 
    myInput.color = 0x000000; 
    showingHint = false; 
    } 
} 

myInput.onFocusLost = function() { 
    if(!showingHint && myInput.text.length == 0) { 
    myInput.text = "Search Terms"; 
    myInput.color = 0xcccccc; 
    showingHint = true; 
    } 
} 

Rappelez-vous, vous voulez seulement changer le texte perdu le focus si l'utilisateur n'a pas changé manuellement texte. Utilisez un booléen distinct pour savoir si vous affichez l'indice ou non, afin que vous puissiez différencier l'utilisateur en tapant manuellement votre texte «indice» en tant que contenu réel. De même, vous ne voulez effacer le contenu de la boîte de saisie que si l'indication est affichée afin de ne pas vous débarrasser accidentellement de l'entrée de l'utilisateur.

4

Il vaut mieux poster le code au lieu du lien. Je poste ce à partir de here

  //Copyright (c) 2008 Jason Kemp 

      //Permission is hereby granted, free of charge, to any person obtaining a copy 
      //of this software and associated documentation files (the "Software"), to deal 
      //in the Software without restriction, including without limitation the rights 
      //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
      //copies of the Software, and to permit persons to whom the Software is 
      //furnished to do so, subject to the following conditions: 

      //The above copyright notice and this permission notice shall be included in 
      //all copies or substantial portions of the Software. 

      //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
      //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
      //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
      //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
      //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
      //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
      //THE SOFTWARE. 

      using System; 
      using System.Runtime.InteropServices; 
      using System.Windows.Forms; 
      using System.Text; 


      public static class Win32Utility 
      { 
       [DllImport("user32.dll", CharSet = CharSet.Auto)] 
       private static extern Int32 SendMessage(IntPtr hWnd, int msg, 
        int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); 

       [DllImport("user32.dll")] 
       private static extern bool SendMessage(IntPtr hwnd, int msg, int wParam, StringBuilder lParam); 

       [DllImport("user32.dll")] 
       private static extern bool GetComboBoxInfo(IntPtr hwnd, ref COMBOBOXINFO pcbi); 

       [StructLayout(LayoutKind.Sequential)] 
       private struct COMBOBOXINFO 
       { 
        public int cbSize; 
        public RECT rcItem; 
        public RECT rcButton; 
        public IntPtr stateButton; 
        public IntPtr hwndCombo; 
        public IntPtr hwndItem; 
        public IntPtr hwndList; 
       } 

       [StructLayout(LayoutKind.Sequential)] 
       private struct RECT 
       { 
        public int left; 
        public int top; 
        public int right; 
        public int bottom; 
       } 

       private const int EM_SETCUEBANNER = 0x1501; 
       private const int EM_GETCUEBANNER = 0x1502; 

       public static void SetCueText(Control control, string text) 
       { 
        if (control is ComboBox) 
        { 
         COMBOBOXINFO info = GetComboBoxInfo(control); 
         SendMessage(info.hwndItem, EM_SETCUEBANNER, 0, text); 
        } 
        else 
        { 
         SendMessage(control.Handle, EM_SETCUEBANNER, 0, text); 
        } 
       } 

       private static COMBOBOXINFO GetComboBoxInfo(Control control) 
       { 
        COMBOBOXINFO info = new COMBOBOXINFO(); 
        //a combobox is made up of three controls, a button, a list and textbox; 
        //we want the textbox 
        info.cbSize = Marshal.SizeOf(info); 
        GetComboBoxInfo(control.Handle, ref info); 
        return info; 
       } 

       public static string GetCueText(Control control) 
       { 
        StringBuilder builder = new StringBuilder(); 
        if (control is ComboBox) 
        { 
         COMBOBOXINFO info = new COMBOBOXINFO(); 
         //a combobox is made up of two controls, a list and textbox; 
         //we want the textbox 
         info.cbSize = Marshal.SizeOf(info); 
         GetComboBoxInfo(control.Handle, ref info); 
         SendMessage(info.hwndItem, EM_GETCUEBANNER, 0, builder); 
        } 
        else 
        { 
         SendMessage(control.Handle, EM_GETCUEBANNER, 0, builder); 
        } 
        return builder.ToString(); 
       } 
      } 
Questions connexes