Textbox avec image de fond pour créer une searchbox

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 446 fois - Téléchargée 16 fois

Contenu du snippet

Pour en de mes projets, j'avais besoin d'une TextBox, avec une icone de "loupe" en arrière plan, pour symboliser une zone de recherche.

Je m'étais déjà fait un petit textbox hérité, pour lui mettre une propriété de "texte par défaut à afficher" (Rechercher un client, par exemple).

Ensuite, j'avais trouvé une source permettant de rajouter un délai avec de lancer le TextChanged, pratique pour pouvoir taper plusieurs caractères sans que la recherche ne soit automatiquement relancée à chaque fois : on attend la fin de la saisie avec de faire la recherche.(ici http://www.codeproject.com/KB/miscctrl/CustomTextBox.aspx)

Il ne me manquait qu'une jolie icône de loupe, sur le côté droit de la zone de recherche.
Et là : galère !
J'ai bien tenté de surcharger le onPaint pour faire rajouter l'icone, mais les effets de bord étaient nombreux. (texte qui disparait, taille de police farfelue, effets de clignottement ...)
Et toutes les recherches que j'ai pu faire sur le net indiquaient le même genre de soucis, ou alors il fallait déployer des moyens énormes pour pas grand chose (comme ici : http://www.codedblog.com/2007/09/17/owner-drawing-a-windowsforms-textbox/)

Et puis je suis tombé sur un article : "Creating a like Vista SearchBox" (http://coderjournal.com/2007/03/creating-a-vista-like-search-box/)
Les captures d'écran me semblait correspondre parfaitement à mon besoin.
J'ai été voir la source, et la solution était en fait toute simple !

Au lieu de vouloir absolument surcharger le onPaint, il suffisait d'ajouter un PictureBox à notre composant TextBox hérité !
Je me suis donc basé là-dessus pour avancer.
Et pour le placement de l'image, il suffit de surcharger le "onResize", et de positionner correctement le pictureBox

Du coup, je ne vais pas m'attarder sur le côté "texte par défaut", et "délai avant le onChange", mais je vais juste donner les quelques lignes de code nécessaire à l'ajout d'une image. Sur une composant Textbox

Avant tout, il faut créer un fichier de ressources dans le projet, avec une icone "loupe.ico"

Source / Exemple :


Imports System.ComponentModel

Public Class TextBoxSearch
    Inherits TextBox

    Private PictureBoxSearch As PictureBox
    
    Public Sub New()

        ' 
        ' pictureBoxSearch
        ' 
        Me.PictureBoxSearch = New System.Windows.Forms.PictureBox()
        Me.PictureBoxSearch.Location = New System.Drawing.Point(0, 0)
        Me.PictureBoxSearch.Name = "PictureBoxSearch"
        Me.PictureBoxSearch.Size = New System.Drawing.Size(16, 16) 'mon icone fera 16x16 pixels
        Me.PictureBoxSearch.TabIndex = 0
        Me.PictureBoxSearch.TabStop = False
        Me.PictureBoxSearch.Image = New Icon(My.Resources.Resources.loupe, 16, 16).ToBitmap() ' mon fichier icone comporte différentes résolutions d'icone, donc j'indique celle que je veux
        Me.Controls.Add(PictureBoxSearch)
        ' pictureBoxSearch
    End Sub

    Protected Overrides Sub OnResize(e As EventArgs)

        MyBase.OnResize(e)
        ' On ajoute 4px à la taille du picturebox, car le Texte box "complet" ajoute 2 px sur chaque côté pour le design
        ' picturebox aligné à droite, et centré en hauteur
        Me.PictureBoxSearch.Location = New System.Drawing.Point(Me.Width - (PictureBoxSearch.Width + 4), CInt((Me.Height - (PictureBoxSearch.Height + 4)) / 2))

    End Sub
End Classe

Conclusion :


Des fois, à trop vouloir faire les choses bien quand on hérite d'un composant, on en oublie les trucs les plus simples !
Ici, il suffisait de positionner un PictureBox, plutôt que de vouloir insérer une icone directement dans le onPaint du composant.

Seul soucis : si on tape "trop" de texte, celui-ci disparait légèrement sous le picture box ... mais bon, est-ce bien grave ?

Ceci étant ma première contribution, n'hésitez pas à me faire part de vos remarques, et à me demander des compléments d'informations si besoin est !

A voir également

Ajouter un commentaire

Commentaires

Bonsoir,

Peut on aussi appliquer le même exemple avec un datagridView ? Si oui comment s'y prendre pour le réaliser. Merci de votre réponse
Messages postés
2
Date d'inscription
jeudi 28 septembre 2006
Statut
Membre
Dernière intervention
30 juin 2011

Bonjour,

Effectivement :)
Là, j'ai fait comme ça car j'avais déjà l'icone de loupe à disposition. Mais c'est clair qu'en la convertissant en PNG, ça le ferait direct.

J'ai surtout voulu montrer le principe de mise en place en fait, et je ne me suis pas trop attardé sur le reste.
Merci !
Messages postés
14694
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
14 août 2020
144
Bonsoir,

C'est une information qui pourra me servir ultérieurement.

Sinon, à la place d'utiliser une icone et de faire :
New Icon(My.Resources.Resources.loupe, 16, 16).ToBitmap()

Tu peux utiliser une image PNG, tu pourra gérer la transparence et ce sera tout de suite une image utilisable.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.