IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

Couleur d'écriture (ForeColor) pour un combobox au style DropDownList


Sujet :

Windows Forms

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2007
    Messages : 47
    Points : 43
    Points
    43
    Par défaut Couleur d'écriture (ForeColor) pour un combobox au style DropDownList
    Bonjour,

    j'essaie que lorsque quelqu'un change la sélection de mon combobox, la couleur d'écriture (ForeColor) devienne rouge. Je veux que mon combobox soit de style DropDownList, car je veux forcer l'usager à faire un choix sans pouvoir écrire dans le contrôle (DropDown).

    Je sais qu'en enlevant la ligne Application.EnableVisualStyles(); de Program.cs ça "réglera" le problème, mais je ne veux pas enlever cette ligne car je ne veux pas que mon programme fasse "année 90".

    Je sais aussi que pour changer la couleur d'un contrôle il faut écrire contrôle.ForeColor = Color.Red;, cependant cela change la couleur de l'écriture de la liste déroulante sans changer celle de l'item sélectionné.

    Je me doute qu'il faut que je modifie la fonction OnPaint de mon combobox, je ne sais cependant pas comment ça fonctionne. Je ne comprends vraiment pas pourquoi ils ont décidé de faire des contrôles sans nous donner la possibilité de changer les couleurs sans avoir à reprogrammer leur fonction OnPaint (J'ai remarqué que le contrôle MonthCalendar a un problème similaire).

    Si quelqu'un a une solution elle serait grandement appréciée, merci !

  2. #2
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour duffmere.
    Mais tu te noies dans un verre d'eau et tu t'enerves mais c'est la meilleure facon de ne pas resoudre ton probleme....En fait il s'agit tout simplement d'ameliorer tes connaissances sur les combo,listbox ,listview et treeview qui permettent tous de personnaliser le dessin de leurs Items directement dans ton form grace......à leur evenement DrawItem dans ton cas precis.

    voici le code de l'item selectionne avec :
    -changement de couleur .
    -changement du font
    -un rectangle de focus Aqua....
    que tu peux mettre directement dans ton form qui utilise ton combobox....
    N'oublie pas de mettre pour combo rawMode=OwnerDrawFixed....

    code du winform avec un combo de "animals" ou ce que tu veux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
     Public Class Form1
            'tableau animals du zoo de vincennes
            Private animals() As String
     
            'Pour performance memoire, declare ici  
            'un Brush utilise pour dessiner dansCombo event DrawItem  du .
            Private ComboDefaultBrush As SolidBrush
            Private ComboDefaultBrushBackColor As SolidBrush
            'Idem pour le  Font que je veux personaliser 
            Private ComboDefaultFont As Font
     
            Public Sub New()
     
                ' Cet appel est requis par le Concepteur Windows Form.
                InitializeComponent()
     
                ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
     
                ' ForeColor et Font par defaut de notre combo exemple.
                Me.ComboBox1.Font = New Font("Arial", 14, FontStyle.Italic)
                Me.ComboBox1.ForeColor = Color.Black
     
                'Mettre DrawMode.OwnerDrawFixed
                Me.ComboBox1.DrawMode = DrawMode.OwnerDrawFixed
                'Mettre ComboBoxStyle.DropDown
                Me.ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
     
                'notre  tableau animals
                animals = New String() {"Elephant", "c r o c o d i l e", "lion"}
     
                ComboBox1.DataSource = animals
                Me.Controls.Add(Me.ComboBox1)
     
            End Sub
     
            ' On doit intercepter  l'evenement  DrawItem .  
            ' Il sert à redefinir color  et font d'un item lors du dessin.
            Private Sub ComboBox1_DrawItem(ByVal sender As Object, _
                ByVal e As System.Windows.Forms.DrawItemEventArgs) _
                Handles ComboBox1.DrawItem
                'ici ton brush,font et brush de focus Aqua
                Dim myBrushSel As Brush
                Dim myFontSel As Font
                Dim brushBackGround As Brush
     
                ' recupere le default brush  using  DrawItemEventArgs
                If ComboDefaultBrush Is Nothing Then
                    ComboDefaultBrush = New SolidBrush(e.ForeColor)
                Else
                    If Not ComboDefaultBrush.Color.Equals(e.ForeColor) Then
                        '  ForeColor du combo a change , aussi dispose du brush & 
                        '  cree un nouveau.
                        ComboDefaultBrush.Dispose()
                        ComboDefaultBrush = New SolidBrush(e.ForeColor)
                    End If
                End If
                ' recupere le default  font using  DrawItemEventArgs
                If ComboDefaultFont Is Nothing Then
                    ComboDefaultFont = New Font(e.Font.FontFamily, e.Font.Size, e.Font.Style)
                Else
                    If Not ComboDefaultFont.FontFamily.Equals(e.Font.FontFamily) Then
                        '  Font du combo a change , aussi dispose du font & 
                        '  cree un nouveau.
                        ComboDefaultFont.Dispose()
                        ComboDefaultFont = New Font(e.Font.FontFamily, e.Font.Size, e.Font.Style)
                    End If
                End If
     
                ' Selectionne le brush approprie  suivant l'etat Selected de l' item 
                ' attention c'est enum de bit-flag .You can't use  "==" to compare them.
                If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                    myBrushSel = New SolidBrush(Color.Red)
                    myFontSel = New Font("Times New Roman", 18, FontStyle.Bold)
                    brushBackGround = New SolidBrush(Color.BlanchedAlmond)
                Else
                    myBrushSel = ComboDefaultBrush
                    myFontSel = ComboDefaultFont
                    brushBackGround = New SolidBrush(e.BackColor)
                End If
     
                ' obligatoire:Draw the background of item :.
                e.DrawBackground()
     
                ' Dessine un rectangle Aqua sous l'tem
                e.Graphics.FillRectangle(brushBackGround, e.Bounds)
     
                ' Draw each string in the array "par dessus" en rouge
                e.Graphics.DrawString(Font.Name, myFontSel, myBrushSel, e.Bounds.X, e.Bounds.Y)
     
     
                ' obligatoire: Draw the focus rectangle if the mouse hovers over an item.
                e.DrawFocusRectangle()
            End Sub
    Par ailleurs l'event MeasureItem peux ajuster la largeur et la hauteur de chaque item si tu veux peindre tes items avec des dimensions variables...suivant la longueur du text de l'item...
    en mettant dans ce cas là DrawMode=OwnerDrawVariable
    voici un code exemple que tu peux mettre dans le form qui contient ton combox de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
     'voici un exemple qui ajuste la hauteur d'un item suivant son 
            'index mais  tu peux remplacer dans le select case 
            'le e.index par Me.ComboBox1.Items(e.Index) pour tester suivant la valeur
            ' de l'item selectionne
            Private Sub ComboBox1_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles ComboBox1.MeasureItem
                Select Case e.Index
                    Case 0
                        e.ItemHeight = 45
                    Case 1
                        e.ItemHeight = 20
                    Case 2
                        e.ItemHeight = 35
                End Select
                'largeur par defaut pour tous les items
                e.ItemWidth = 260
     
     
     
            End Sub
    Tu peux aussi agrementer en desinant avec des gradientbrush..............
    bon code..................

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2007
    Messages : 47
    Points : 43
    Points
    43
    Par défaut
    Merci pour la réponse! Je vais essayer de l'implémenter en C# et je verrai ce que ça donne. Je vous tiens au courant !

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2007
    Messages : 47
    Points : 43
    Points
    43
    Par défaut
    Je viens de terminer d'implémenter votre solution, j'ai mis des valeurs par défaut pour la couleur de fond et le "Font" voici ce que ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    private void cbPriorite1_DrawItem(object sender, DrawItemEventArgs e)
            {
                Brush myBrushSel;           
     
                if (((e.State & DrawItemState.Selected) == DrawItemState.Selected))
                {
                    myBrushSel = new SolidBrush(Color.Red);
                }
                else
                {
                myBrushSel = new SolidBrush(Color.Black);
                }
     
                e.DrawBackground();
                e.Graphics.FillRectangle(new SolidBrush(Color.White), e.Bounds);
                e.Graphics.DrawString(priorityChoices[e.Index], new Font("Calibri", (float)9.75,FontStyle.Bold), myBrushSel, e.Bounds.X, e.Bounds.Y);
                e.DrawFocusRectangle();
            }
    Il y a cependant certains problèmes que je vois avec cette solution :

    1. L'item sélectionné se dessine en rouge même si la sélection ne change pas (si on resélectionne l'item déjà sélectionné par exemple ou juste si on expensionne la liste sans faire de nouveau choix)
    2. Étant donné que j'ai 15 combobox à faire cela rajoute 300 lignes dans mon code juste pour gérer la couleur de la sélection de mes combobox, je trouve que c'est quand même beaucoup pour une fonction qui, selon moi, devrait être supportée de base par ce genre de contrôle.

    Peut être que c'est .NET qui m'a rendu paresseux, je vais continuer à voir si je ne peux pas améliorer cette solution mais je reste ouvert à d'autres options si certains en ont.

    Merci !

  5. #5
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    rebonjour duffmere...
    Premierement voic l'equivalent c# du code vb.net et sans zapper les lignes....qui fonctionne comme un charme.....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace ComboxDrawItemCSharp
    {
        public partial class Form4 : Form
        {
            // tableau animals du zoo de vincennes
            private string[] animals; 
     
            // Pour performance memoire, declare ici  
            // un Brush utilise pour dessiner dansCombo event DrawItem  du .
            private SolidBrush ComboDefaultBrush ;
     
            // Idem pour le  Font que je veux personaliser 
            private  Font ComboDefaultFont ;
            public Form4()
            {
                InitializeComponent();
     
                //ForeColor et Font par defaut de notre combo exemple.
                this.priorityChoices.Font =new Font("Arial", 14, FontStyle.Italic);
                this.priorityChoices.ForeColor = Color.Black;
                this.priorityChoices.BackColor = Color.YellowGreen;
                // Mettre DrawMode.OwnerDrawFixed
                this.priorityChoices.DrawMode = DrawMode.OwnerDrawFixed;
                //Mettre ComboBoxStyle.DropDown
                this.priorityChoices.DropDownStyle = ComboBoxStyle.DropDownList;
     
                //notre  tableau animals
                animals = new String[] {"Elephant", "c r o c o d i l e", "lion"};
     
                this.priorityChoices.DataSource = animals;
                this.Controls.Add(this.priorityChoices);
            }
     
            private void priorityChoices_DrawItem(object sender, DrawItemEventArgs e)
            {
                 // ici ton brush,font et brush de focus Aqua
                    Brush myBrushSel;
                    Font myFontSel ;
                    Brush brushBackGround ;
                    // lignes zappees allegrement
                    // le color et le Font defaults du combox doivent etre 
                    //recuperes de l'argument DrawItemEventArgs sous peine de deboires
     
                    // recupere le default brush  using  
                    if ( ComboDefaultBrush ==null)
                    {
                        ComboDefaultBrush = new SolidBrush(e.ForeColor);
                    }
                    else
                    {  
                        if (!ComboDefaultBrush.Color.Equals(e.ForeColor)) 
                        {
                            //  ForeColor du combo a change. Reinit
                            ComboDefaultBrush.Dispose();
                            ComboDefaultBrush = new SolidBrush(e.ForeColor);
                        }
                    } 
     
                    if ( ComboDefaultFont ==null)
                    {
                        ComboDefaultFont =new Font(e.Font.FontFamily, e.Font.Size, e.Font.Style);
                    }
                    else
                    {
                        if (!ComboDefaultFont.FontFamily.Equals(e.Font.FontFamily)) 
                        {
                            //  Font du combo a change.Reinit . 
                            ComboDefaultFont.Dispose();
                            ComboDefaultFont = new Font(e.Font.FontFamily, e.Font.Size, e.Font.Style);
                        }
                    }       
     
                    // ton code repris correctement
     
                    if (((e.State & DrawItemState.Selected) == DrawItemState.Selected))
                    {
                        myBrushSel = new SolidBrush(Color.Red);
                        myFontSel = new Font("Calibri", (float)9.75, FontStyle.Bold);
                        brushBackGround = new SolidBrush(Color.White);
     
                    }
                    else
                    {
                        //sinon utilise defaults value.Apres Reinit bien sur!
                        myBrushSel = ComboDefaultBrush;
                        myFontSel = ComboDefaultFont;
                        brushBackGround =new SolidBrush(e.BackColor);
                    }
     
                    //dessin de l'item
                    e.DrawBackground();
                    e.Graphics.FillRectangle(brushBackGround, e.Bounds);
     
                    e.Graphics.DrawString(this.priorityChoices.Items[e.Index].ToString(), myFontSel , myBrushSel, e.Bounds.X, e.Bounds.Y);
                    e.DrawFocusRectangle();
            }
        }
    }
    Maintenant si tu as 300 lignes de code c'est un probleme de design et non pas de frappe de code car tu n'as pas prevu dans ton architecture des classe ce cas de figure et la possibilite d' initialiser tous les controles utilises dans ton appli....
    En tout cas dans un tel scenario de fait accompli la seule solution si tu veux personnaliser ton combo c'est de coder un customcombo dote des prop ColorItem et FontItem et d'ecrire un seule fois le code pour DrawItem dans ce customcontrol ...
    De remplacer tes combo concernes par cestui-la et d'affecter les couleurs et les font appropries sur le designer....
    code du custom combo:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace ComboxDrawItemCSharp
    {
        public partial class CustomComboBox : ComboBox
        {
            public CustomComboBox()
            {
                InitializeComponent();
                // init. necessaire au ForeColor du CustomComboBox
                this.ColorItem = this.ForeColor;
            }
            // prop sera visible sur designer
            [Browsable(true)]
            [Description ("Couleur Item Selectione")]
            [Category("Apparence")]
            public Color ColorItem { get; set; }
     
     
            private void CustomComboBox_DrawItem(object sender, DrawItemEventArgs e)
            {
                    e.DrawBackground();
     
                    string s = this.Items[e.Index].ToString();
                    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
    	            {
        		          e.Graphics.DrawString(s, this.Font, new SolidBrush(this.ColorItem), e.Bounds.X, e.Bounds.Y);
    	            }
                    else
    	            {
                        e.Graphics.DrawString(s, this.Font, new SolidBrush(e.ForeColor), e.Bounds.X, e.Bounds.Y);
    	            }
                    e.DrawFocusRectangle();
                    }
        }
    }
    le "simplistic" code du winform qui l'utilises:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace ComboxDrawItemCSharp
    {
        public partial class Form2 : Form
        {
             // tableau animals du zoo de vincennes
            private string[] animals;
     
            public Form2()
            {
                InitializeComponent();
                //ForeColor et Font par defaut de notre combo exemple.
                this.customPriorityChoices.Font = new Font("Arial", 14, FontStyle.Bold);
                this.customPriorityChoices.ForeColor = Color.Black;
                this.customPriorityChoices.BackColor = Color.BlanchedAlmond;
                // Mettre DrawMode.OwnerDrawFixed
                this.customPriorityChoices.DrawMode = DrawMode.OwnerDrawFixed;
                //Mettre ComboBoxStyle.DropDown
                this.customPriorityChoices.DropDownStyle = ComboBoxStyle.DropDownList;
     
                //notre  tableau animals
                animals = new String[] { "Elephant", "c r o c o d i l e", "lion" };
     
                this.customPriorityChoices.DataSource = animals;
                this.Controls.Add(this.customPriorityChoices);
            }
     
        }
    }
    bon code....................

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2007
    Messages : 47
    Points : 43
    Points
    43
    Par défaut
    Je me doutais aussi qu'il faudrait que je me fasse un combobox custom mais je n'étais pas trop certain de la manière comment m'y prendre pour le DrawItem. Merci beaucoup pour le code que vous m'avez fourni, j'ai du le modifier quelque peu pour que ça fonctionne mais maintenant le contrôle répond comme je le voulais.

    Juste mentionner que la ligne ne fonctionne pas dans le constructeur du combobox, je l'ai donc enlevé. J'ai également dû ajouter un eventhandler pour le DrawItem dans ce même constructeur sinon l'événement ne se faisait jamais appeler.

    Merci encore !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Couleur d'un élément d'une ComboBox
    Par freestyler dans le forum Delphi
    Réponses: 16
    Dernier message: 10/01/2017, 17h43
  2. [RQT] Aide pour un ComboBox
    Par TheOrY dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 11/04/2007, 10h19
  3. Réponses: 1
    Dernier message: 07/12/2005, 15h21
  4. [FLASH MX2004] Explication pour les comboBox
    Par Sorento dans le forum Flash
    Réponses: 7
    Dernier message: 18/06/2005, 23h47
  5. [C#] Format des dates pour une ComboBox...
    Par frechy dans le forum Windows Forms
    Réponses: 5
    Dernier message: 07/01/2005, 17h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo