web-dev-qa-db-fra.com

Dessiner un bouton transparent

J'essaie de créer un bouton transparent dans C # (.NET 3.5 SP1) à utiliser dans mon application WinForms. J'ai tout essayé pour obtenir le bouton pour être transparent (il doit indiquer le fond dégradé sous le bouton) mais il ne fonctionne tout simplement pas.

Voici le code que j'utilise:

public class ImageButton : ButtonBase, IButtonControl
{
    public ImageButton()
    {
        this.SetStyle(
            ControlStyles.SupportsTransparentBackColor | 
            ControlStyles.OptimizedDoubleBuffer | 
            ControlStyles.AllPaintingInWmPaint | 
            ControlStyles.ResizeRedraw | 
            ControlStyles.UserPaint, true);
        this.BackColor = Color.Transparent;
    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        Graphics g = pevent.Graphics;
        g.FillRectangle(Brushes.Transparent, this.ClientRectangle);
        g.DrawRectangle(Pens.Black, this.ClientRectangle);
    }


    // rest of class here...

}

Le problème est que le bouton semble saisir une mémoire d'interface utilisateur aléatoire de quelque part et se remplir de tampon de l'interface utilisateur de Visual Studio (en mode de conception). Au moment de l'exécution, il saisit un tampon de zéro'd et est complètement noir.

Mon objectif ultime est de peindre une image sur un bouton invisible au lieu du rectangle. Le concept devrait rester la même cependant. Lorsque l'utilisateur plane sur le bouton, une forme de type bouton est dessinée.

Des idées?

Edit: Merci tout le monde, les suivants ont fonctionné pour moi :

public class ImageButton : Control, IButtonControl
{
    public ImageButton()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        SetStyle(ControlStyles.Opaque, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        this.BackColor = Color.Transparent;

    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        Graphics g = pevent.Graphics;
        g.DrawRectangle(Pens.Black, this.ClientRectangle);
    }


    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // don't call the base class
        //base.OnPaintBackground(pevent);
    }


    protected override CreateParams CreateParams
    {
        get
        {
            const int WS_EX_TRANSPARENT = 0x20;
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= WS_EX_TRANSPARENT;
            return cp;
        }
    }

    // rest of class here...
}
21
rein

Dans Winforms, il y a quelques astuces pour permettre un contrôle de son arrière-plan correctement peint lors de l'utilisation de la transparence. Vous pouvez ajouter ce code à l'ONUPAINT ou sur ONPAINTBackground pour obtenir les commandes que vous avez dans l'arrière-plan étant peinte:

if (this.Parent != null)
{
 GraphicsContainer cstate = pevent.Graphics.BeginContainer();
 pevent.Graphics.TranslateTransform(-this.Left, -this.Top);
 Rectangle clip = pevent.ClipRectangle;
 clip.Offset(this.Left, this.Top);
 PaintEventArgs pe = new PaintEventArgs(pevent.Graphics, clip);

 //Paint the container's bg
 InvokePaintBackground(this.Parent, pe);
 //paints the container fg
 InvokePaint(this.Parent, pe);
 //restores graphics to its original state
 pevent.Graphics.EndContainer(cstate);
}
else
  base.OnPaintBackground(pevent); // or base.OnPaint(pevent);...
10
jmservera

Je ne suis pas sûr que ButtonBase prend en charge la transparence ... Avez-vous vérifié cela?

J'ai écrit un certain nombre de contrôles transparents, mais j'ai toujours hérité de contrôler ou d'Usercontrol.

Lorsque vous souhaitez bloquer une peinture de contrôle, c'est l'arrière-plan - vous devriez remplacer sur PainTbackground au lieu d'Onpaint et n'appelle pas la classe de base.

Remplir un rectangle avec des brosses.Transparent est drôle mais vous peignez avec une couleur invisible sur ce qui y est esrédé. Ou de la mettre d'une autre manière: ça ne fait rien!

1
Dan Byström

Je sais que cette question est ancienne, mais si quelqu'un ne veut pas créer de contrôle pour le faire, je suis venu avec ce code d'un autre article et a changé une méthode d'extension.

public static void ToTransparent(this System.Windows.Forms.Button Button,
     System.Drawing.Color TransparentColor)
{
    Bitmap bmp = ((Bitmap)Button.Image);
    bmp.MakeTransparent(TransparentColor);
    int x = (Button.Width - bmp.Width) / 2;
    int y = (Button.Height - bmp.Height) / 2;
    Graphics gr = Button.CreateGraphics();
    gr.DrawImage(bmp, x, y);
}

Et l'appel comme:

buttonUpdate.ToTransparent(Color.Magenta);
1
Kevin