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 :

[C#][2.0]UserCtl Degradé backcolor + Bord arrondi


Sujet :

Windows Forms

  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 160
    Par défaut [C#][2.0]UserCtl Degradé backcolor + Bord arrondi
    Bonjour,

    J'ai surchargé la methode onPaint de mmon usercontrol afin de lui affecter un fond degradé comme ceci :

    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
     
            protected override void OnPaint(PaintEventArgs e)
     
            {           
     
                if (e == null)
     
                    return;
     
                if (e.Graphics == null)
     
                    return;
     
                Graphics g = e.Graphics;
     
     
     
     
     
                Rectangle r = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height);
     
                LinearGradientBrush lb = new LinearGradientBrush(r, GUICst.GUICstColorBlue, GUICst.GUICstColorBlue,
     
                                                                       LinearGradientMode.ForwardDiagonal);
     
                e.Graphics.FillRectangle(lb, e.ClipRectangle);
     
     
     
            }
    Deja est ce la bonne methode ?
    comment affecter cette couleur a ma proprieté backcolor ?
    en fait lorsque je vais mettre des controles dans ce usercontrol (this.add(Ctl) )
    je veux que les controls qui y seront ajouté aient la meme couleur .
    il suffit d'affecter la proprieté backcolor de mon usercontrol par ma couleur degradé ?

    Edit :
    En fait la question simple est comment affecté à la proprieté backcolor de mon control une couleur degradé.
    parce quen fait jai des controls qui viennent sur ce control et qui sont transparent ...
    comme je dessine un rectangle que je peinds en couleur degradé, ma proprieté backcolor n'est pas en phase.
    du coup mes controles qui viennent au dessus sont transparent mais ont la couleur de backcolor qui n'est pas degradé



    Ensuite jai une autre question ... comment faire des bords ronds (arrondies) à mon usercontrol ?

    Merci

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    324
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 324
    Par défaut
    pour le degrader : fait toi une image sous paint et met la en background je crois pas qu'il existe de moyen de definir une couleur degrader : c'est comme si tu demander un fond rouge et jaune a petits pois
    Sinon pour les bord rond .... tu veux parler du style windows xp ?
    si oui alors essaye la methode EnableVisualStyles()
    Je suis pas sur du tout la c'est juste que en c++ notre form se lance avec ce paramètre et que on a un comment au dessus :
    Citation Envoyé par le commentaire
    // Enabling Windows XP visual effects before any controls are created

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 160
    Par défaut
    Citation Envoyé par ekinox17
    pour le degrader : fait toi une image sous paint et met la en background je crois pas qu'il existe de moyen de definir une couleur degrader : c'est comme si tu demander un fond rouge et jaune a petits pois
    Sinon pour les bord rond .... tu veux parler du style windows xp ?
    si oui alors essaye la methode EnableVisualStyles()
    Je suis pas sur du tout la c'est juste que en c++ notre form se lance avec ce paramètre et que on a un comment au dessus :
    Citation Envoyé par le commentaire
    // Enabling Windows XP visual effects before any controls are created
    pour le degrader il faut utiliser LinearGradientBrush
    cela fonctionne
    mais je narrive pas a affecter a ma proprieté backcolor de mon usercontrol.
    je ne peux pas en fait faire de fond en "image" car le developpeur/user peut definir lui meme son propre degradé de couleur dans le panel de choix de windows..



    sinon pour les bords rond , ce sont des usercontrols
    le enablevisualstyle ne fonctionne pas.
    je ne trouve pas un moyen simple de faire cela ...

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Par défaut
    Pour un dégradé de couleur, il faut effectivement utiliser une LinearGradientBrush.
    BackColor ne peut pas gérer un dégradé puisque c'est un type Color et non Brush.

    Tu peux surcharger la méthode OnPaintBackGround pour dessiner le fond.

    Il ne faut pas recréer de brush à chaque fois. Les classes Brush doivent être libérées par Dispose() car elles réservent des ressources système.
    Il vaut mieux créer une Brush dans le constructeur(ou à l'affectation d'une propriété) et la conserver comme membre pour la réutiliser.

    Pour créer un contrôle non rectangle, il faut définir sa propriété Region.

  5. #5
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 160
    Par défaut
    Citation Envoyé par NicolasG
    Pour un dégradé de couleur, il faut effectivement utiliser une LinearGradientBrush.
    BackColor ne peut pas gérer un dégradé puisque c'est un type Color et non Brush.

    Tu peux surcharger la méthode OnPaintBackGround pour dessiner le fond.

    Il ne faut pas recréer de brush à chaque fois. Les classes Brush doivent être libérées par Dispose() car elles réservent des ressources système.
    Il vaut mieux créer une Brush dans le constructeur(ou à l'affectation d'une propriété) et la conserver comme membre pour la réutiliser.
    ok merci.
    mais donc si je met un control en backcolor transparent sur mon usercontrol que je cree et dessine le fond, il prendra jamais la "couleur" de mon fond degradé que je dessine moi meme ?

    Pour créer un contrôle non rectangle, il faut définir sa propriété Region.
    aurait tu un code ou un lien stp ?

  6. #6
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 160
    Par défaut
    c'est bon j'ai reussi pour les arrondis
    et la redefinission de la region .

    Par contre quand je met un control par dessus mon usercontrol
    la transparence n'est toujours pas geré

    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
     
     
      protected override void OnPaintBackground(PaintEventArgs e)
            {
                #region Graphics
                if (e == null)
                    return;
                if (e.Graphics == null)
                    return;
                Graphics g = e.Graphics;
                #endregion
     
                #region BAckground
                if (e.ClipRectangle.Width > 0 & e.ClipRectangle.Height > 0)
                {
                    Rectangle r = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height);
                    using(_lb = GetBrushColorGradient(ref r))
                    e.Graphics.FillRectangle(_lb, e.ClipRectangle);
     
     
     
                    GraphicsPath gp = new GraphicsPath();
                    Pen p = new Pen(Color.White,2);
                    float radius = 15;
                    gp.AddLine(e.ClipRectangle.X + radius, e.ClipRectangle.Y, e.ClipRectangle.X + e.ClipRectangle.Width - (radius * 2), e.ClipRectangle.Y);
                    gp.AddArc(e.ClipRectangle.X + e.ClipRectangle.Width - (radius * 2), e.ClipRectangle.Y, radius * 2, radius * 2, 270, 90);
                    gp.AddLine(e.ClipRectangle.X + e.ClipRectangle.Width, e.ClipRectangle.Y + radius, e.ClipRectangle.X + e.ClipRectangle.Width, e.ClipRectangle.Y + e.ClipRectangle.Height - (radius * 2));
                    gp.AddArc(e.ClipRectangle.X + e.ClipRectangle.Width - (radius * 2), e.ClipRectangle.Y + e.ClipRectangle.Height - (radius * 2), radius * 2, radius * 2, 0, 90);
                    gp.AddLine(e.ClipRectangle.X + e.ClipRectangle.Width - (radius * 2), e.ClipRectangle.Y + e.ClipRectangle.Height, e.ClipRectangle.X + radius, e.ClipRectangle.Y + e.ClipRectangle.Height);
                    gp.AddArc(e.ClipRectangle.X, e.ClipRectangle.Y + e.ClipRectangle.Height - (radius * 2), radius * 2, radius * 2, 90, 90);
                    gp.AddLine(e.ClipRectangle.X, e.ClipRectangle.Y + e.ClipRectangle.Height- (radius * 2), e.ClipRectangle.X, e.ClipRectangle.Y + radius);
                    gp.AddArc(e.ClipRectangle.X, e.ClipRectangle.Y, radius * 2, radius * 2, 180, 90);
                    gp.CloseFigure();
                    g.DrawPath(p, gp);
     
                    this.Region = new System.Drawing.Region(gp);
                    ControlPaint.DrawBorder3D(g, r, Border3DStyle.RaisedInner);
     
                    gp.Dispose();
     
     
     
                }

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Par défaut
    Une précision sur PaintEventArgs.ClipRectangle : ce rectangle est la partie du contrôle à redessiner. Si une partie seulement a été cachée et est à redessiner, tu vas avoir des surprises.

    Dans ton code, à chaque appel de OnPaintBackground(), tu recrée un nouveau brush
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _lb = GetBrushColorGradient(ref r)
    et une nouvelle région
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.Region = new System.Drawing.Region(gp);
    pour les libérer à chaque fois.

    C'est la méthode la moins efficace possible.
    Il faut conserver ces objets et les recréer uniquement lors du redimensionnement du contrôle. Pour ça, il faut surcharger Control.SetBoundsCore()

  8. #8
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 160
    Par défaut
    Citation Envoyé par NicolasG
    Une précision sur PaintEventArgs.ClipRectangle : ce rectangle est la partie du contrôle à redessiner. Si une partie seulement a été cachée et est à redessiner, tu vas avoir des surprises.

    Dans ton code, à chaque appel de OnPaintBackground(), tu recrée un nouveau brush
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _lb = GetBrushColorGradient(ref r)
    et une nouvelle région
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.Region = new System.Drawing.Region(gp);
    pour les libérer à chaque fois.

    C'est la méthode la moins efficace possible.
    Il faut conserver ces objets et les recréer uniquement lors du redimensionnement du contrôle. Pour ça, il faut surcharger Control.SetBoundsCore()

    ok .

    il faut donc que je crée mon brush dans la surcharge de cette methode ?
    en lui specifiant le rectanche this.bounds ?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
            {
                base.SetBoundsCore(x, y, width, height, specified);
                if (_lb ==null)
                    _lb = GUI.GUICst.GetBrushColorGradient(this.Bounds, _StyleColor);
            }
    et remplacer cliprectangle par this.bounds ?

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Par défaut
    C'est ça.
    Avec quand même un défaut, il faut recréer _lb dans tous les cas donc pas de test _lb==null

    Il faut aussi mettre à jour Control.Region dans SetBoundsCore().

  10. #10
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 160
    Par défaut
    Citation Envoyé par NicolasG
    C'est ça.
    Avec quand même un défaut, il faut recréer _lb dans tous les cas donc pas de test _lb==null

    Il faut aussi mettre à jour Control.Region dans SetBoundsCore().
    Merci beaucoup
    je fais ca cette apres midi ...

    c'est sympa le developpement de controls avec GDI+ en fait ;-)
    ca change du fonctionnel

  11. #11
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 160
    Par défaut
    Citation Envoyé par NicolasG
    Il faut aussi mettre à jour Control.Region dans SetBoundsCore().
    Si je simplifie mon code :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
            {
                base.SetBoundsCore(x, y, width, height, specified);            
                this.Region = new Region(Bounds);
     
                _lb = new LinearGradientBrush(Bounds, Color.Red, Color.Green,
                                                                       LinearGradientMode.BackwardDiagonal);
     
            }
    dans paintbackground surchargé

    je fais juste

    g.FillRectangle(_lb, this.Bounds);


    mais mon usercontrol est tout noir ...
    sauf quand je lagrandi en fait ma zone repeinte n'est pas bonne ...
    pourtant elle doit correspondre a bounds non ?

  12. #12
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Par défaut
    Le problème vient du fait que Bounds définit la position et taille dans le contrôle parent
    Que tu utilise PaintEventArgs.Graphics, les coordonnées n'ont pas la même origine. L'origine est alors le coin haut gauche du contrôle et non de son parent.
    Il faut donc utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Rectangle(0, 0, this.Width, this.Height)
    plutôt que
    Il n'y a pas de contre-indication à créer un GraphicsPath pour faire des coins arrondis mais attention à l'origine (0,0).

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

Discussions similaires

  1. Bord arrondi !
    Par muriel76 dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 26/04/2007, 15h16
  2. bord arrondi d'un tableau
    Par ijklm dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 19/02/2007, 17h17
  3. Menus avec bord arrondi pour site fluide
    Par HADES62 dans le forum Mise en page CSS
    Réponses: 8
    Dernier message: 14/02/2007, 21h22
  4. [Débutant] Bouton avec les bords arrondis
    Par zwieback dans le forum Graphisme
    Réponses: 3
    Dernier message: 12/06/2006, 13h18
  5. [CSS] - une div aux bords arrondis ?
    Par 10-nice dans le forum Mise en page CSS
    Réponses: 12
    Dernier message: 23/09/2005, 15h47

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